123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 'use strict'
- const log = require('./logger').create()
- class Executor {
- constructor (capturedBrowsers, config, emitter) {
- this.capturedBrowsers = capturedBrowsers
- this.config = config
- this.emitter = emitter
- this.executionScheduled = false
- this.errorsScheduled = []
- this.pendingCount = 0
- this.runningBrowsers = null
- this.emitter.on('run_complete', () => this.onRunComplete())
- this.emitter.on('browser_complete', () => this.onBrowserComplete())
- }
- schedule () {
- if (this.capturedBrowsers.length === 0) {
- log.warn(`No captured browser, open ${this.config.protocol}//${this.config.hostname}:${this.config.port}${this.config.urlRoot}`)
- return false
- } else if (this.capturedBrowsers.areAllReady()) {
- log.debug('All browsers are ready, executing')
- log.debug(`Captured ${this.capturedBrowsers.length} browsers`)
- this.executionScheduled = false
- this.capturedBrowsers.clearResults()
- this.pendingCount = this.capturedBrowsers.length
- this.runningBrowsers = this.capturedBrowsers.clone()
- this.emitter.emit('run_start', this.runningBrowsers)
- this.socketIoSockets.emit('execute', this.config.client)
- return true
- } else {
- log.info('Delaying execution, these browsers are not ready: ' + this.capturedBrowsers.getNonReady().join(', '))
- this.executionScheduled = true
- return false
- }
- }
- /**
- * Schedule an error to be reported
- * @param {string} errorMessage
- * @returns {boolean} a boolean indicating whether or not the error was handled synchronously
- */
- scheduleError (errorMessage) {
- // We don't want to interfere with any running test.
- // Verify that no test is running before reporting the error.
- if (this.capturedBrowsers.areAllReady()) {
- log.warn(errorMessage)
- const errorResult = {
- success: 0,
- failed: 0,
- skipped: 0,
- error: errorMessage,
- exitCode: 1
- }
- const noBrowsersStartedTests = []
- this.emitter.emit('run_start', noBrowsersStartedTests) // A run cannot complete without being started
- this.emitter.emit('run_complete', noBrowsersStartedTests, errorResult)
- return true
- } else {
- this.errorsScheduled.push(errorMessage)
- return false
- }
- }
- onRunComplete () {
- if (this.executionScheduled) {
- this.schedule()
- }
- if (this.errorsScheduled.length) {
- const errorsToReport = this.errorsScheduled
- this.errorsScheduled = []
- errorsToReport.forEach((error) => this.scheduleError(error))
- }
- }
- onBrowserComplete () {
- this.pendingCount--
- if (!this.pendingCount) {
- // Ensure run_complete is emitted in the next tick
- // so it is never emitted before browser_complete
- setTimeout(() => {
- this.emitter.emit('run_complete', this.runningBrowsers, this.runningBrowsers.getResults())
- })
- }
- }
- }
- Executor.factory = function (capturedBrowsers, config, emitter) {
- return new Executor(capturedBrowsers, config, emitter)
- }
- module.exports = Executor
|