siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
154 lines (107 loc) • 4.81 kB
JavaScript
/*
Siesta 5.6.1
Copyright(c) 2009-2022 Bryntum AB
https://bryntum.com/contact
https://bryntum.com/products/siesta/license
*/
Role('Siesta.Launcher.Runner.WebDriverNodeJS.WithTunnel', {
has : {
tunnelProcess : null,
tunnelId : null,
tunnelName : null,
tunnelInfo : null,
tunnelRestartTimeout : 10000,
maxTunnelRestartAttempts : 3
},
override : {
initTunnelId : function () {
this.tunnelId = String(Math.floor(Math.random() * 1e16))
},
shutdownTunnelProcess : function (forcefullTimeout) {
var tunnelProcess = this.tunnelProcess
if (!tunnelProcess) return Promise.resolve()
var me = this
return new Promise(function (resolve) {
tunnelProcess.on('exit', function () {
me.tunnelProcess = null
resolve()
})
me.print("Closing " + me.tunnelName + " tunnel")
tunnelProcess.kill()
setTimeout(function () {
if (me.tunnelProcess) {
me.debug("Closing " + me.tunnelName + " tunnel forcefully")
me.tunnelProcess.kill('SIGKILL')
}
}, forcefullTimeout || 10000)
})
},
destroy : function () {
var me = this
return this.SUPER().then(function () {
return me.shutdownTunnelProcess()
})[ 'catch' ](function () {
return me.shutdownTunnelProcess()
})
},
launchTunnel : function (cmd, args, options, onLine, attemptNumber) {
var me = this
var readline = require('readline')
var launcher = me.launcher
attemptNumber = attemptNumber || 1
me.print("Launching local tunnel to " + this.tunnelName + ": " + this.tunnelInfo)
var child = me.tunnelProcess = require('child_process').spawn(cmd, args, options)
var readLineInterface = readline.createInterface({ input : child.stdout })
return new Promise(function (resolve, reject) {
var ready = false
var output = ''
var preventOnExit = false
var doRestart = function (exitCode, timeout) {
timeout = timeout || me.tunnelRestartTimeout
if (attemptNumber < me.maxTunnelRestartAttempts) {
me.warn("Restarting the tunnel after " + (timeout / 1000) + "s")
setTimeout(function () {
resolve(me.launchTunnel(cmd, args, options, onLine, ++attemptNumber))
}, timeout)
} else {
resolve(new Error("Starting local tunnel to " + me.tunnelName + " has failed with exit code: " + exitCode))
}
}
readLineInterface.on('line', function (line) {
output += line + '\n'
me.debug("Tunnel sdtout: " + line)
var res
if (
(onLine instanceof RegExp) && onLine.test(line) ||
typeof onLine == 'function' && (res = onLine(line))
) {
if (res == 'restart') {
preventOnExit = true
me.shutdownTunnelProcess(100).then(function () {
doRestart('UPDATE', 1000)
})
return
}
ready = true
readLineInterface.close()
resolve(me)
}
})
child.on('exit', function (exitCode, signal) {
me.tunnelProcess = null
if (preventOnExit) return
if (ready) {
if (launcher.isRunning) {
me.printError(me.tunnelName + " tunnel has stopped during test suite execution")
launcher.gracefulShutdown()
}
return
}
me.printError("Starting local tunnel to " + me.tunnelName + " has failed with exit code: " + exitCode + ", output:\n" + output)
doRestart(exitCode)
})
})
}
}
// eof methods
})