Skip to content

Commit

Permalink
feat(client): update banner with connection, test status, ping times (#…
Browse files Browse the repository at this point in the history
…3611)

The banner is visible in videos so we can have some client side
info on the state if it breaks.
  • Loading branch information
johnjbarton committed Jan 13, 2021
1 parent 68c4a3a commit 4bf90f7
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 39 deletions.
10 changes: 9 additions & 1 deletion client/karma.js
Expand Up @@ -2,7 +2,8 @@ var stringify = require('../common/stringify')
var constant = require('./constants')
var util = require('../common/util')

function Karma (socket, iframe, opener, navigator, location, document) {
function Karma (updater, socket, iframe, opener, navigator, location, document) {
this.updater = updater
var startEmitted = false
var karmaNavigating = false
var self = this
Expand Down Expand Up @@ -190,6 +191,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
}

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

if (!startEmitted) {
socket.emit('start', { total: null })
self.updater.updateTestStatus('start')
startEmitted = true
}

if (resultsBufferLimit === 1) {
self.updater.updateTestStatus('result')
return socket.emit('result', convertedResult)
}

resultsBuffer.push(convertedResult)

if (resultsBuffer.length === resultsBufferLimit) {
socket.emit('result', resultsBuffer)
self.updater.updateTestStatus('result')
resultsBuffer = []
}
}
Expand All @@ -232,6 +237,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
socket.emit('result', resultsBuffer)
resultsBuffer = []
}

// A test could have incorrectly issued a navigate. Wait one turn
// to ensure the error from an incorrect navigate is processed.
setTimeout(() => {
Expand All @@ -240,6 +246,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
}

socket.emit('complete', result || {})
self.updater.updateTestStatus('complete')

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

socket.on('execute', function (cfg) {
self.updater.updateTestStatus('execute')
// reset startEmitted and reload the iframe
startEmitted = false
self.config = cfg
Expand Down
4 changes: 2 additions & 2 deletions client/main.js
Expand Up @@ -20,6 +20,6 @@ var socket = io(location.host, {
})

// instantiate the updater of the view
new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers'))
window.karma = new Karma(socket, util.elm('context'), window.open,
var updater = new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers'))
window.karma = new Karma(updater, socket, util.elm('context'), window.open,
window.navigator, window.location, window.document)
62 changes: 48 additions & 14 deletions client/updater.js
Expand Up @@ -21,26 +21,60 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) {
}
}

function updateBanner (status) {
return function (param) {
if (!titleElement || !bannerElement) {
return
}
var paramStatus = param ? status.replace('$', param) : status
titleElement.textContent = 'Karma v' + VERSION + ' - ' + paramStatus
bannerElement.className = status === 'connected' ? 'online' : 'offline'
var connectionText = 'never-connected'
var testText = 'loading'
var pingText = ''

function updateBanner () {
if (!titleElement || !bannerElement) {
return
}
titleElement.textContent = `Karma v ${VERSION} - ${connectionText}; test: ${testText}; ${pingText}`
bannerElement.className = connectionText === 'connected' ? 'online' : 'offline'
}

function updateConnectionStatus (connectionStatus) {
connectionText = connectionStatus || connectionText
updateBanner()
}
function updateTestStatus (testStatus) {
testText = testStatus || testText
updateBanner()
}
function updatePingStatus (pingStatus) {
pingText = pingStatus || pingText
updateBanner()
}

socket.on('connect', () => {
updateConnectionStatus('connected')
})
socket.on('disconnect', () => {
updateConnectionStatus('disconnected')
})
socket.on('reconnecting', (sec) => {
updateConnectionStatus(`reconnecting in ${sec} seconds`)
})
socket.on('reconnect', () => {
updateConnectionStatus('reconnected')
})
socket.on('reconnect_failed', () => {
updateConnectionStatus('reconnect_failed')
})

socket.on('connect', updateBanner('connected'))
socket.on('disconnect', updateBanner('disconnected'))
socket.on('reconnecting', updateBanner('reconnecting in $ seconds...'))
socket.on('reconnect', updateBanner('connected'))
socket.on('reconnect_failed', updateBanner('failed to reconnect'))
socket.on('info', updateBrowsersInfo)
socket.on('disconnect', function () {
socket.on('disconnect', () => {
updateBrowsersInfo([])
})

socket.on('ping', () => {
updatePingStatus('ping...')
})
socket.on('pong', (latency) => {
updatePingStatus(`ping ${latency}ms`)
})

return { updateTestStatus: updateTestStatus }
}

module.exports = StatusUpdater
76 changes: 59 additions & 17 deletions static/karma.js
Expand Up @@ -12,7 +12,8 @@ var stringify = require('../common/stringify')
var constant = require('./constants')
var util = require('../common/util')

function Karma (socket, iframe, opener, navigator, location, document) {
function Karma (updater, socket, iframe, opener, navigator, location, document) {
this.updater = updater
var startEmitted = false
var karmaNavigating = false
var self = this
Expand Down Expand Up @@ -200,6 +201,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
}

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

if (!startEmitted) {
socket.emit('start', { total: null })
self.updater.updateTestStatus('start')
startEmitted = true
}

if (resultsBufferLimit === 1) {
self.updater.updateTestStatus('result')
return socket.emit('result', convertedResult)
}

resultsBuffer.push(convertedResult)

if (resultsBuffer.length === resultsBufferLimit) {
socket.emit('result', resultsBuffer)
self.updater.updateTestStatus('result')
resultsBuffer = []
}
}
Expand All @@ -242,6 +247,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
socket.emit('result', resultsBuffer)
resultsBuffer = []
}

// A test could have incorrectly issued a navigate. Wait one turn
// to ensure the error from an incorrect navigate is processed.
setTimeout(() => {
Expand All @@ -250,6 +256,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
}

socket.emit('complete', result || {})
self.updater.updateTestStatus('complete')

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

socket.on('execute', function (cfg) {
self.updater.updateTestStatus('execute')
// reset startEmitted and reload the iframe
startEmitted = false
self.config = cfg
Expand Down Expand Up @@ -340,8 +348,8 @@ var socket = io(location.host, {
})

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

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

function updateBanner (status) {
return function (param) {
if (!titleElement || !bannerElement) {
return
}
var paramStatus = param ? status.replace('$', param) : status
titleElement.textContent = 'Karma v' + VERSION + ' - ' + paramStatus
bannerElement.className = status === 'connected' ? 'online' : 'offline'
var connectionText = 'never-connected'
var testText = 'loading'
var pingText = ''

function updateBanner () {
if (!titleElement || !bannerElement) {
return
}
titleElement.textContent = `Karma v ${VERSION} - ${connectionText}; test: ${testText}; ${pingText}`
bannerElement.className = connectionText === 'connected' ? 'online' : 'offline'
}

socket.on('connect', updateBanner('connected'))
socket.on('disconnect', updateBanner('disconnected'))
socket.on('reconnecting', updateBanner('reconnecting in $ seconds...'))
socket.on('reconnect', updateBanner('connected'))
socket.on('reconnect_failed', updateBanner('failed to reconnect'))
function updateConnectionStatus (connectionStatus) {
connectionText = connectionStatus || connectionText
updateBanner()
}
function updateTestStatus (testStatus) {
testText = testStatus || testText
updateBanner()
}
function updatePingStatus (pingStatus) {
pingText = pingStatus || pingText
updateBanner()
}

socket.on('connect', () => {
updateConnectionStatus('connected')
})
socket.on('disconnect', () => {
updateConnectionStatus('disconnected')
})
socket.on('reconnecting', (sec) => {
updateConnectionStatus(`reconnecting in ${sec} seconds`)
})
socket.on('reconnect', () => {
updateConnectionStatus('reconnected')
})
socket.on('reconnect_failed', () => {
updateConnectionStatus('reconnect_failed')
})

socket.on('info', updateBrowsersInfo)
socket.on('disconnect', function () {
socket.on('disconnect', () => {
updateBrowsersInfo([])
})

socket.on('ping', () => {
updatePingStatus('ping...')
})
socket.on('pong', (latency) => {
updatePingStatus(`ping ${latency}ms`)
})

return { updateTestStatus: updateTestStatus }
}

module.exports = StatusUpdater
Expand Down
19 changes: 14 additions & 5 deletions test/client/karma.spec.js
Expand Up @@ -6,15 +6,21 @@ var ContextKarma = require('../../context/karma')
var MockSocket = require('./mocks').Socket

describe('Karma', function () {
var socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow
var windowDocument, elements
var updater, socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow
var windowDocument, elements, mockTestStatus

function setTransportTo (transportName) {
socket._setTransportNameTo(transportName)
socket.emit('connect')
}

beforeEach(function () {
mockTestStatus = ''
updater = {
updateTestStatus: (s) => {
mockTestStatus = s
}
}
socket = new MockSocket()
iframe = {}
windowNavigator = {}
Expand All @@ -23,7 +29,7 @@ describe('Karma', function () {
elements = [{ style: {} }, { style: {} }]
windowDocument = { querySelectorAll: sinon.stub().returns(elements) }

k = new ClientKarma(socket, iframe, windowStub, windowNavigator, windowLocation, windowDocument)
k = new ClientKarma(updater, socket, iframe, windowStub, windowNavigator, windowLocation, windowDocument)
clientWindow = {
karma: k
}
Expand Down Expand Up @@ -217,7 +223,7 @@ describe('Karma', function () {
it('should report browser id', function () {
windowLocation.search = '?id=567'
socket = new MockSocket()
k = new ClientKarma(socket, {}, windowStub, windowNavigator, windowLocation)
k = new ClientKarma(updater, socket, {}, windowStub, windowNavigator, windowLocation)

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

socket.emit('execute', config)
assert(mockTestStatus === 'execute')

clock.tick(1)
var CURRENT_URL = iframe.src
ck.complete()
clock.tick(1)
assert.strictEqual(iframe.src, CURRENT_URL)
assert(mockTestStatus === 'complete')
})

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

0 comments on commit 4bf90f7

Please sign in to comment.