siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
178 lines (127 loc) • 6.41 kB
JavaScript
/*
Siesta 5.6.1
Copyright(c) 2009-2022 Bryntum AB
https://bryntum.com/contact
https://bryntum.com/products/siesta/license
*/
Class('Siesta.Launcher.Runner.WebDriverNodeJS.SauceLabs', {
isa : Siesta.Launcher.Runner.WebDriverNodeJS,
does : [
Siesta.Launcher.Runner.WebDriverNodeJS.WithTunnel
],
has : {
// increased page poll interval to reduce trafic
pagePollInterval : 5000,
resolutionCapName : 'screenResolution',
tunnelName : 'SauceLabs'
},
methods : {
onWebDriverInstatiationException : function (e, builder, capabilities) {
var str = String(e)
var match
if (match = /(Resolution you specified is not available .*)/.exec(str)) {
var options = this.dispatcher.options
var width = options.width || Siesta.Launcher.Page.WebDriverNodeJS.prototype.width
var height = options.height || Siesta.Launcher.Page.WebDriverNodeJS.prototype.height
this.warn("Requested resolution " + width + 'x' + height + " is not supported for this OS/browser/version/device combo. Retrying w/o requesting any specific resolution.")
capabilities.set(this.resolutionCapName, undefined)
builder.withCapabilities(capabilities)
return true
}
if (match = /Unsupported OS\/browser\/version\/device combo/.exec(str)) {
return false
}
return this.SUPER(e)
},
buildCapabilities : function () {
var caps = this.SUPERARG(arguments)
var options = this.dispatcher.options
caps.set('recordVideo', options[ 'saucelabs-enable-video' ] ? 'true' : 'false')
caps.set('recordScreenshots', options[ 'saucelabs-enable-screenshots' ] ? 'true' : 'false')
var tunnelId = this.tunnelId || options[ 'saucelabs-tunnel-identifier' ]
if (tunnelId) {
caps.set('tunnelIdentifier', tunnelId)
}
return caps
},
// promised method
setup : function () {
var me = this
return this.SUPER().then(function () {
var launcher = me.launcher
var options = launcher.options
var sl = options.sl
if (!sl) throw new Error("This runner should only be used when saucelabs is enabled")
if (!sl.shortCut || sl.noTunnel) return me
me.initTunnelId()
var args = []
args.push('-u', sl.userName);
args.push('-k', sl.key);
args.push('-t', sl.tunneledDomains || 'localhost');
args.push('--tunnel-identifier', me.tunnelId);
// this option is possibly not required, added as an experiment
args.push('--no-proxy-caching')
if (options.coverage) {
args.push('--proxy', '127.0.0.1:' + me.dispatcher.instrumentationProxyPort)
} else
if (options[ 'proxy-host' ]) {
args.push('--proxy', options.WRAPPER.getProxyHostPort())
if (options[ 'proxy-user' ] && options[ 'proxy-password' ]) {
args.push('--proxy-userpwd', options[ 'proxy-user' ] + ':' + options[ 'proxy-password' ])
}
}
if (options[ 'saucelabs-log-file' ]) args.push('--logfile', options[ 'saucelabs-log-file' ])
me.tunnelInfo = sl.userName
return me.launchTunnel(
launcher.binDir + '/binary/saucelabs/' + launcher.getPlatformId() + '/bin/sc' + (launcher.isWindows ? '.exe' : ''),
args,
undefined,
// the . in regexp is required! it indicates the 2nd entry of `you may start your tests` phrase
// (it is encountered 1st as: "Please wait for 'you may start your tests' to start your tests.")
/you may start your tests\./i
)
})
},
// should never reject
// this method "blocks" the
onPageCompleted : function (page, exception, notLaunchedById) {
var me = this
var launcher = me.launcher
var options = launcher.options
var sl = options.sl
return this.SUPER(page, exception, notLaunchedById).then(function () {
var jobId = page.getSessionId()
var passed = page.dispatcher.chunkPassed(page.chunkTask, notLaunchedById)
me.debug('Marking SauceLabs job [' + jobId + '] as ' + (passed ? 'PASSED' : 'FAILED'))
// the saucelabs job update doesn't have to block the other tests, but it has to be
// completed before the launcher exits, so add it to the "resolveBeforeDestroy" array
me.resolveBeforeDestroy.push(new Promise(function (resolve) {
var request = require('https').request({
method : 'PUT',
host : 'saucelabs.com',
path : '/rest/v1/' + sl.userName + '/jobs/' + jobId,
auth : sl.userName + ':' + sl.key,
timeout : 10000
}, function (response) {
response.setEncoding('utf8')
var rawData = '';
response.on('data', function (chunk) { return rawData += chunk })
response.on('end', function () {
resolve()
});
})
request.on('error', resolve)
request.end(JSON.stringify({
passed : passed
}))
}).then(function () {
me.debug('Job [' + jobId + '] updated')
return Promise.resolve()
}))
// return immediately
return Promise.resolve()
})
}
}
// eof methods
})