UNPKG

@theintern/digdug

Version:

Dig Dug. A simple abstraction library for downloading and launching WebDriver service tunnels.

344 lines 13.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var Tunnel_1 = tslib_1.__importDefault(require("./Tunnel")); var fs_1 = require("fs"); var os_1 = require("os"); var path_1 = require("path"); var common_1 = require("@theintern/common"); var url_1 = require("url"); var util_1 = require("./lib/util"); var scVersion = '4.7.1'; var SauceLabsTunnel = (function (_super) { tslib_1.__extends(SauceLabsTunnel, _super); function SauceLabsTunnel(options) { return _super.call(this, Object.assign({ accessKey: process.env.SAUCE_ACCESS_KEY, directDomains: [], directory: path_1.join(__dirname, 'saucelabs'), domainAuthentication: [], environmentUrl: 'https://saucelabs.com/rest/v1/info/platforms/webdriver', fastFailDomains: [], isSharedTunnel: false, logTrafficStats: 0, scVersion: scVersion, skipSslDomains: [], tunnelDomains: [], useProxyForTunnel: false, username: process.env.SAUCE_USERNAME, }, options || {})) || this; } Object.defineProperty(SauceLabsTunnel.prototype, "auth", { get: function () { return (this.username || '') + ":" + (this.accessKey || ''); }, enumerable: false, configurable: true }); Object.defineProperty(SauceLabsTunnel.prototype, "executable", { get: function () { var platform = this.platform === 'darwin' ? 'osx' : this.platform; var architecture = this.architecture; if (platform === 'osx' || platform === 'win32' || (platform === 'linux' && architecture === 'x64')) { return path_1.join(this.directory, 'sc-' + this.scVersion + '-' + platform + '/bin/sc' + (platform === 'win32' ? '.exe' : '')); } else { return 'java'; } }, enumerable: false, configurable: true }); Object.defineProperty(SauceLabsTunnel.prototype, "extraCapabilities", { get: function () { var capabilities = {}; if (this.tunnelId) { capabilities['tunnel-identifier'] = this.tunnelId; } return capabilities; }, enumerable: false, configurable: true }); Object.defineProperty(SauceLabsTunnel.prototype, "isDownloaded", { get: function () { return util_1.fileExists(this.executable === 'java' ? path_1.join(this.directory, 'Sauce-Connect.jar') : path_1.join(this.executable)); }, enumerable: false, configurable: true }); Object.defineProperty(SauceLabsTunnel.prototype, "url", { get: function () { var platform = this.platform === 'darwin' ? 'osx' : this.platform; var architecture = this.architecture; var url = 'https://saucelabs.com/downloads/sc-' + this.scVersion + '-'; if (platform === 'osx' || platform === 'win32') { url += platform + '.zip'; } else if (platform === 'linux' && architecture === 'x64') { url += platform + '.tar.gz'; } else { url = 'https://saucelabs.com/downloads/Sauce-Connect-3.1-r32.zip'; } return url; }, enumerable: false, configurable: true }); SauceLabsTunnel.prototype._postDownloadFile = function (data, options) { var _this = this; return _super.prototype._postDownloadFile.call(this, data, options).then(function () { if (_this.executable !== 'java') { fs_1.chmodSync(_this.executable, parseInt('0755', 8)); } }); }; SauceLabsTunnel.prototype._makeNativeArgs = function (proxy) { var args = ['-u', this.username, '-k', this.accessKey]; if (proxy) { if (proxy.host) { args.push('-p', proxy.host); } if (proxy.auth) { args.push('-w', proxy.auth); } } if (this.domainAuthentication.length) { this.domainAuthentication.forEach(function (domain) { var url = url_1.parse(domain); args.push('-a', url.hostname + ":" + url.port + ":" + url.auth); }); } this.logTrafficStats && args.push('-z', String(Math.floor(this.logTrafficStats / 1000))); this.verbose && args.push('-v'); return args; }; SauceLabsTunnel.prototype._makeJavaArgs = function (proxy) { var args = ['-jar', 'Sauce-Connect.jar', this.username, this.accessKey]; this.logFileSize && args.push('-g', String(this.logFileSize)); this.squidOptions && args.push('-S', this.squidOptions); this.verbose && args.push('-d'); if (proxy) { proxy.hostname && args.push('-p', proxy.hostname + (proxy.port ? ':' + proxy.port : '')); if (proxy.auth) { var auth = proxy.auth.split(':'); args.push('-u', auth[0], '-X', auth[1]); } } return args; }; SauceLabsTunnel.prototype._makeArgs = function (readyFile) { if (!this.username || !this.accessKey) { throw new Error('SauceLabsTunnel requires a username and access key'); } var proxy = this.proxy ? url_1.parse(this.proxy) : undefined; var args = this.executable === 'java' ? this._makeJavaArgs(proxy) : this._makeNativeArgs(proxy); args.push('-P', this.port, '-f', readyFile); this.directDomains.length && args.push('-D', this.directDomains.join(',')); this.tunnelDomains.length && args.push('-t', this.tunnelDomains.join(',')); this.fastFailDomains.length && args.push('-F', this.fastFailDomains.join(',')); this.isSharedTunnel && args.push('-s'); this.logFile && args.push('-l', this.logFile); this.pacFile && args.push('--pac', this.pacFile); this.pidFile && args.push('--pidfile', this.pidFile); this.restUrl && args.push('-x', this.restUrl); this.skipSslDomains.length && args.push('-B', this.skipSslDomains.join(',')); this.tunnelId && args.push('-i', this.tunnelId); this.useProxyForTunnel && args.push('-T'); this.vmVersion && args.push('-V', this.vmVersion); return args; }; SauceLabsTunnel.prototype.sendJobState = function (jobId, data) { var url = url_1.parse(this.restUrl || 'https://saucelabs.com/rest/v1/'); url.auth = this.username + ':' + this.accessKey; url.pathname += this.username + '/jobs/' + jobId; var payload = JSON.stringify({ build: data.buildId, 'custom-data': data.extra, name: data.name, passed: data.success, public: data.visibility, tags: data.tags, }); return common_1.request(url_1.format(url), { method: 'put', data: payload, headers: { 'Content-Length': String(Buffer.byteLength(payload, 'utf8')), 'Content-Type': 'application/x-www-form-urlencoded', }, password: this.accessKey, username: this.username, proxy: this.proxy, }).then(function (response) { return response.text().then(function (text) { if (text) { var data_1 = JSON.parse(text); if (data_1.error) { throw new Error(data_1.error); } if (response.status !== 200) { throw new Error("Server reported " + response.status + " with: " + text); } } else { throw new Error("Server reported " + response.status + " with no other data."); } }); }); }; SauceLabsTunnel.prototype._start = function (executor) { var _this = this; var readyFile = path_1.join(os_1.tmpdir(), 'saucelabs-' + Date.now()); var readMessage; var readStartupMessage; var readRunningMessage; var readStatus; var task = this._makeChild(function (child, resolve, reject) { readStartupMessage = function (message) { function fail(message) { reject(new Error(message)); return true; } if (message.indexOf('Error: response: ') === 0) { try { var error = /(\{[\s\S]*\})/.exec(message); if (error) { var data = JSON.parse(error[1]); return fail(data.error); } } catch (error) { } } if (message.indexOf('Error: ') === 0) { if (/open file limit \d+ is too low/.test(message) || /Sauce Labs recommends setting it/.test(message) || /HTTP response code indicated failure/.test(message)) { return false; } return fail(message.slice('Error: '.length)); } if (message.indexOf('Sauce Connect is up, you may start your tests.') === 0) { resolve(); return true; } return readStatus(message); }; readRunningMessage = function (message) { if (message.indexOf('Problem connecting to Sauce Labs REST API') > -1) { util_1.kill(child.pid); } return readStatus(message); }; readStatus = function (message) { if (message && message.indexOf('Please wait for') === -1 && message.indexOf('Sauce Connect is up') === -1 && message.indexOf('Sauce Connect') !== 0 && message.indexOf('Using CA certificate bundle') === -1 && message.indexOf('You may start your tests') === -1) { _this.emit({ type: 'status', target: _this, status: message, }); } return false; }; readMessage = readStartupMessage; fs_1.watchFile(readyFile, { persistent: false, interval: 1007 }, function (current, previous) { if (Number(current.mtime) === Number(previous.mtime)) { return; } resolve(); }); _this._handle = util_1.on(child.stdout, 'data', function (data) { if (!readMessage) { return; } String(data) .split('\n') .some(function (message) { var delimiter = message.indexOf(' - '); if (delimiter > -1) { message = message.slice(delimiter + 3); } return readMessage(message.trim()); }); }); executor(child, resolve, reject); }, readyFile); task .then(function () { fs_1.unwatchFile(readyFile); readMessage = readStatus; readRunningMessage(''); readMessage = undefined; }) .catch(function () { }); return task; }; SauceLabsTunnel.prototype._normalizeEnvironment = function (environment) { var windowsMap = { 'Windows 2003': 'Windows XP', 'Windows 2008': 'Windows 7', 'Windows 2012': 'Windows 8', 'Windows 2012 R2': 'Windows 8.1', 'Windows 10': 'Windows 10', }; var browserMap = { microsoftedge: 'MicrosoftEdge', }; var os = environment.os; var platformName = os; var platformVersion; if (os.indexOf('Windows') === 0) { os = windowsMap[os] || os; platformName = 'Windows'; platformVersion = os.slice('Windows '.length); } else if (os.indexOf('Mac') === 0) { platformName = 'OS X'; platformVersion = os.slice('Mac '.length); } var platform = platformName + (platformVersion ? ' ' + platformVersion : ''); var browserName = browserMap[environment.api_name] || environment.api_name; var version = environment.short_version; return { platform: platform, platformName: platformName, platformVersion: platformVersion, browserName: browserName, browserVersion: version, version: version, descriptor: environment, intern: { platform: platform, browserName: browserName, version: version, }, }; }; return SauceLabsTunnel; }(Tunnel_1.default)); exports.default = SauceLabsTunnel; //# sourceMappingURL=SauceLabsTunnel.js.map