Updated the files.
This commit is contained in:
parent
1553e6b971
commit
753967d4f5
23418 changed files with 3784666 additions and 0 deletions
271
my-app/node_modules/karma/lib/browser.js
generated
vendored
Executable file
271
my-app/node_modules/karma/lib/browser.js
generated
vendored
Executable file
|
@ -0,0 +1,271 @@
|
|||
'use strict'
|
||||
|
||||
const BrowserResult = require('./browser_result')
|
||||
const helper = require('./helper')
|
||||
const logger = require('./logger')
|
||||
|
||||
const CONNECTED = 'CONNECTED' // The browser is connected but not yet been commanded to execute tests.
|
||||
const CONFIGURING = 'CONFIGURING' // The browser has been told to execute tests; it is configuring before tests execution.
|
||||
const EXECUTING = 'EXECUTING' // The browser is executing the tests.
|
||||
const EXECUTING_DISCONNECTED = 'EXECUTING_DISCONNECTED' // The browser is executing the tests, but temporarily disconnect (waiting for socket reconnecting).
|
||||
const DISCONNECTED = 'DISCONNECTED' // The browser got completely disconnected (e.g. browser crash) and can be only restored with a restart of execution.
|
||||
|
||||
class Browser {
|
||||
constructor (id, fullName, collection, emitter, socket, timer, disconnectDelay,
|
||||
noActivityTimeout, singleRun, clientConfig) {
|
||||
this.id = id
|
||||
this.fullName = fullName
|
||||
this.name = helper.browserFullNameToShort(fullName)
|
||||
this.lastResult = new BrowserResult()
|
||||
this.disconnectsCount = 0
|
||||
this.activeSockets = [socket]
|
||||
this.noActivityTimeout = noActivityTimeout
|
||||
this.singleRun = singleRun
|
||||
this.clientConfig = clientConfig
|
||||
this.collection = collection
|
||||
this.emitter = emitter
|
||||
this.socket = socket
|
||||
this.timer = timer
|
||||
this.disconnectDelay = disconnectDelay
|
||||
|
||||
this.log = logger.create(this.name)
|
||||
|
||||
this.noActivityTimeoutId = null
|
||||
this.pendingDisconnect = null
|
||||
this.setState(CONNECTED)
|
||||
}
|
||||
|
||||
init () {
|
||||
this.log.info(`Connected on socket ${this.socket.id} with id ${this.id}`)
|
||||
|
||||
this.bindSocketEvents(this.socket)
|
||||
this.collection.add(this)
|
||||
this.emitter.emit('browser_register', this)
|
||||
}
|
||||
|
||||
setState (toState) {
|
||||
this.log.debug(`${this.state} -> ${toState}`)
|
||||
this.state = toState
|
||||
}
|
||||
|
||||
onKarmaError (error) {
|
||||
if (this.isNotConnected()) {
|
||||
this.lastResult.error = true
|
||||
}
|
||||
this.emitter.emit('browser_error', this, error)
|
||||
this.refreshNoActivityTimeout()
|
||||
}
|
||||
|
||||
onInfo (info) {
|
||||
if (helper.isDefined(info.dump)) {
|
||||
this.emitter.emit('browser_log', this, info.dump, 'dump')
|
||||
}
|
||||
|
||||
if (helper.isDefined(info.log)) {
|
||||
this.emitter.emit('browser_log', this, info.log, info.type)
|
||||
} else if (helper.isDefined(info.total)) {
|
||||
if (this.state === EXECUTING) {
|
||||
this.lastResult.total = info.total
|
||||
}
|
||||
} else if (!helper.isDefined(info.dump)) {
|
||||
this.emitter.emit('browser_info', this, info)
|
||||
}
|
||||
|
||||
this.refreshNoActivityTimeout()
|
||||
}
|
||||
|
||||
onStart (info) {
|
||||
if (info.total === null) {
|
||||
this.log.warn('Adapter did not report total number of specs.')
|
||||
}
|
||||
|
||||
this.lastResult = new BrowserResult(info.total)
|
||||
this.setState(EXECUTING)
|
||||
this.emitter.emit('browser_start', this, info)
|
||||
this.refreshNoActivityTimeout()
|
||||
}
|
||||
|
||||
onComplete (result) {
|
||||
if (this.isNotConnected()) {
|
||||
this.setState(CONNECTED)
|
||||
this.lastResult.totalTimeEnd()
|
||||
|
||||
this.emitter.emit('browsers_change', this.collection)
|
||||
this.emitter.emit('browser_complete', this, result)
|
||||
|
||||
this.clearNoActivityTimeout()
|
||||
}
|
||||
}
|
||||
|
||||
onSocketDisconnect (reason, disconnectedSocket) {
|
||||
helper.arrayRemove(this.activeSockets, disconnectedSocket)
|
||||
if (this.activeSockets.length) {
|
||||
this.log.debug(`Disconnected ${disconnectedSocket.id}, still have ${this.getActiveSocketsIds()}`)
|
||||
return
|
||||
}
|
||||
|
||||
if (this.isConnected()) {
|
||||
this.disconnect(`Client disconnected from CONNECTED state (${reason})`)
|
||||
} else if ([CONFIGURING, EXECUTING].includes(this.state)) {
|
||||
this.log.debug(`Disconnected during run, waiting ${this.disconnectDelay}ms for reconnecting.`)
|
||||
this.setState(EXECUTING_DISCONNECTED)
|
||||
|
||||
this.pendingDisconnect = this.timer.setTimeout(() => {
|
||||
this.lastResult.totalTimeEnd()
|
||||
this.lastResult.disconnected = true
|
||||
this.disconnect(`reconnect failed before timeout of ${this.disconnectDelay}ms (${reason})`)
|
||||
this.emitter.emit('browser_complete', this)
|
||||
}, this.disconnectDelay)
|
||||
|
||||
this.clearNoActivityTimeout()
|
||||
}
|
||||
}
|
||||
|
||||
reconnect (newSocket, clientSaysReconnect) {
|
||||
if (!clientSaysReconnect || this.state === DISCONNECTED) {
|
||||
this.log.info(`Disconnected browser returned on socket ${newSocket.id} with id ${this.id}.`)
|
||||
this.setState(CONNECTED)
|
||||
|
||||
// The disconnected browser is already part of the collection.
|
||||
// Update the collection view in the UI (header on client.html)
|
||||
this.emitter.emit('browsers_change', this.collection)
|
||||
// Notify the launcher
|
||||
this.emitter.emit('browser_register', this)
|
||||
// Execute tests if configured to do so.
|
||||
if (this.singleRun) {
|
||||
this.execute()
|
||||
}
|
||||
} else if (this.state === EXECUTING_DISCONNECTED) {
|
||||
this.log.debug('Lost socket connection, but browser continued to execute. Reconnected ' +
|
||||
`on socket ${newSocket.id}.`)
|
||||
this.setState(EXECUTING)
|
||||
} else if ([CONNECTED, CONFIGURING, EXECUTING].includes(this.state)) {
|
||||
this.log.debug(`Rebinding to new socket ${newSocket.id} (already have ` +
|
||||
`${this.getActiveSocketsIds()})`)
|
||||
}
|
||||
|
||||
if (!this.activeSockets.some((s) => s.id === newSocket.id)) {
|
||||
this.activeSockets.push(newSocket)
|
||||
this.bindSocketEvents(newSocket)
|
||||
}
|
||||
|
||||
if (this.pendingDisconnect) {
|
||||
this.timer.clearTimeout(this.pendingDisconnect)
|
||||
}
|
||||
|
||||
this.refreshNoActivityTimeout()
|
||||
}
|
||||
|
||||
onResult (result) {
|
||||
if (Array.isArray(result)) {
|
||||
result.forEach(this.onResult, this)
|
||||
} else if (this.isNotConnected()) {
|
||||
this.lastResult.add(result)
|
||||
this.emitter.emit('spec_complete', this, result)
|
||||
}
|
||||
this.refreshNoActivityTimeout()
|
||||
}
|
||||
|
||||
execute () {
|
||||
this.activeSockets.forEach((socket) => socket.emit('execute', this.clientConfig))
|
||||
this.setState(CONFIGURING)
|
||||
this.refreshNoActivityTimeout()
|
||||
}
|
||||
|
||||
getActiveSocketsIds () {
|
||||
return this.activeSockets.map((s) => s.id).join(', ')
|
||||
}
|
||||
|
||||
disconnect (reason) {
|
||||
this.log.warn(`Disconnected (${this.disconnectsCount} times) ${reason || ''}`)
|
||||
this.disconnectsCount++
|
||||
this.emitter.emit('browser_error', this, `Disconnected ${reason || ''}`)
|
||||
this.remove()
|
||||
}
|
||||
|
||||
remove () {
|
||||
this.setState(DISCONNECTED)
|
||||
this.collection.remove(this)
|
||||
}
|
||||
|
||||
refreshNoActivityTimeout () {
|
||||
if (this.noActivityTimeout) {
|
||||
this.clearNoActivityTimeout()
|
||||
|
||||
this.noActivityTimeoutId = this.timer.setTimeout(() => {
|
||||
this.lastResult.totalTimeEnd()
|
||||
this.lastResult.disconnected = true
|
||||
this.disconnect(`, because no message in ${this.noActivityTimeout} ms.`)
|
||||
this.emitter.emit('browser_complete', this)
|
||||
}, this.noActivityTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
clearNoActivityTimeout () {
|
||||
if (this.noActivityTimeout && this.noActivityTimeoutId) {
|
||||
this.timer.clearTimeout(this.noActivityTimeoutId)
|
||||
this.noActivityTimeoutId = null
|
||||
}
|
||||
}
|
||||
|
||||
bindSocketEvents (socket) {
|
||||
// TODO: check which of these events are actually emitted by socket
|
||||
socket.on('disconnect', (reason) => this.onSocketDisconnect(reason, socket))
|
||||
socket.on('start', (info) => this.onStart(info))
|
||||
socket.on('karma_error', (error) => this.onKarmaError(error))
|
||||
socket.on('complete', (result) => this.onComplete(result))
|
||||
socket.on('info', (info) => this.onInfo(info))
|
||||
socket.on('result', (result) => this.onResult(result))
|
||||
}
|
||||
|
||||
isConnected () {
|
||||
return this.state === CONNECTED
|
||||
}
|
||||
|
||||
isNotConnected () {
|
||||
return !this.isConnected()
|
||||
}
|
||||
|
||||
serialize () {
|
||||
return {
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
isConnected: this.state === CONNECTED
|
||||
}
|
||||
}
|
||||
|
||||
toString () {
|
||||
return this.name
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return {
|
||||
id: this.id,
|
||||
fullName: this.fullName,
|
||||
name: this.name,
|
||||
state: this.state,
|
||||
lastResult: this.lastResult,
|
||||
disconnectsCount: this.disconnectsCount,
|
||||
noActivityTimeout: this.noActivityTimeout,
|
||||
disconnectDelay: this.disconnectDelay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Browser.factory = function (
|
||||
id, fullName, /* capturedBrowsers */ collection, emitter, socket, timer,
|
||||
/* config.browserDisconnectTimeout */ disconnectDelay,
|
||||
/* config.browserNoActivityTimeout */ noActivityTimeout,
|
||||
/* config.singleRun */ singleRun,
|
||||
/* config.client */ clientConfig) {
|
||||
return new Browser(id, fullName, collection, emitter, socket, timer,
|
||||
disconnectDelay, noActivityTimeout, singleRun, clientConfig)
|
||||
}
|
||||
|
||||
Browser.STATE_CONNECTED = CONNECTED
|
||||
Browser.STATE_CONFIGURING = CONFIGURING
|
||||
Browser.STATE_EXECUTING = EXECUTING
|
||||
Browser.STATE_EXECUTING_DISCONNECTED = EXECUTING_DISCONNECTED
|
||||
Browser.STATE_DISCONNECTED = DISCONNECTED
|
||||
|
||||
module.exports = Browser
|
Loading…
Add table
Add a link
Reference in a new issue