UNPKG

@theintern/digdug

Version:

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

239 lines 9.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var fs_1 = require("fs"); var path_1 = require("path"); var common_1 = require("@theintern/common"); var Tunnel_1 = tslib_1.__importDefault(require("./Tunnel")); var url_1 = require("url"); var util_1 = require("./lib/util"); var BrowserStackTunnel = (function (_super) { tslib_1.__extends(BrowserStackTunnel, _super); function BrowserStackTunnel(options) { return _super.call(this, Object.assign({ accessKey: process.env.BROWSERSTACK_ACCESS_KEY, automateOnly: true, directory: path_1.join(__dirname, 'browserstack'), environmentUrl: 'https://www.browserstack.com/automate/browsers.json', forceLocal: false, hostname: 'hub.browserstack.com', killOtherTunnels: false, port: '443', protocol: 'https', servers: [], skipServerValidation: true, username: process.env.BROWSERSTACK_USERNAME, }, options || {})) || this; } Object.defineProperty(BrowserStackTunnel.prototype, "auth", { get: function () { return (this.username || '') + ":" + (this.accessKey || ''); }, enumerable: false, configurable: true }); Object.defineProperty(BrowserStackTunnel.prototype, "executable", { get: function () { return path_1.join(this.directory, "BrowserStackLocal" + (this.platform === 'win32' ? '.exe' : '')); }, enumerable: false, configurable: true }); Object.defineProperty(BrowserStackTunnel.prototype, "extraCapabilities", { get: function () { var capabilities = { 'browserstack.local': 'true', }; if (this.tunnelId) { capabilities['browserstack.localIdentifier'] = this.tunnelId; } return capabilities; }, enumerable: false, configurable: true }); Object.defineProperty(BrowserStackTunnel.prototype, "url", { get: function () { var platform = this.platform; var architecture = this.architecture; var url = 'https://www.browserstack.com/browserstack-local/BrowserStackLocal-'; if (platform === 'darwin' && (architecture === 'x64' || architecture === 'arm64')) { url += platform + '-x64'; } else if (platform === 'win32') { url += platform; } else if (platform === 'linux' && (architecture === 'ia32' || architecture === 'x64')) { url += platform + '-' + architecture; } else { throw new Error(platform + ' on ' + architecture + ' is not supported'); } url += '.zip'; return url; }, enumerable: false, configurable: true }); BrowserStackTunnel.prototype._postDownloadFile = function (data, options) { var _this = this; return _super.prototype._postDownloadFile.call(this, data, options).then(function () { var executable = _this.executable; fs_1.chmodSync(executable, parseInt('0755', 8)); }); }; BrowserStackTunnel.prototype._makeArgs = function () { var _values = []; for (var _i = 0; _i < arguments.length; _i++) { _values[_i] = arguments[_i]; } if (!this.username || !this.accessKey) { throw new Error('BrowserStackTunnel requires a username and access key'); } var args = [ this.accessKey, this.servers .map(function (server) { var url = url_1.parse(String(server)); return [ url.hostname, url.port, url.protocol === 'https:' ? 1 : 0, ].join(','); }) .join(','), ]; this.automateOnly && args.push('-onlyAutomate'); this.forceLocal && args.push('-forcelocal'); this.killOtherTunnels && args.push('-force'); this.skipServerValidation && args.push('-skipCheck'); this.tunnelId && args.push('-localIdentifier', this.tunnelId); this.verbose && args.push('-v'); var aProxy = typeof this.tunnelProxy !== 'undefined' ? this.tunnelProxy : this.proxy; if (aProxy) { var proxy = url_1.parse(aProxy); proxy.hostname && args.push('-proxyHost', proxy.hostname); proxy.port && args.push('-proxyPort', proxy.port); if (proxy.auth) { var auth = proxy.auth.split(':'); args.push('-proxyUser', auth[0], '-proxyPass', auth[1]); } } return args; }; BrowserStackTunnel.prototype.sendJobState = function (jobId, data) { var payload = JSON.stringify({ status: data.status || data.success ? 'completed' : 'error', }); var url = "https://www.browserstack.com/automate/sessions/" + jobId + ".json"; return common_1.request(url, { method: 'put', data: payload, headers: { 'Content-Length': String(Buffer.byteLength(payload, 'utf8')), 'Content-Type': 'application/json', }, password: this.accessKey, username: this.username, proxy: this.proxy, }).then(function (response) { if (response.status < 200 || response.status >= 300) { return response.text().then(function (text) { throw new Error(text || "Server reported " + response.status + " with no other data."); }); } }); }; BrowserStackTunnel.prototype._start = function (executor) { var _this = this; return this._makeChild(function (child, resolve, reject) { var handle = util_1.on(child.stdout, 'data', function (data) { data = String(data); var error = /\s*\*\*\* Error: (.*)$/m.exec(data); if (error) { handle.destroy(); reject(new Error("The tunnel reported: " + error[1])); } else if (data.indexOf('You can now access your local server(s) in our remote browser') > -1) { handle.destroy(); resolve(); } else { var line = data.replace(/^\s+/, '').replace(/\s+$/, ''); if (/^BrowserStackLocal v/.test(line) || /^Connecting to BrowserStack/.test(line) || /^Connected/.test(line)) { _this.emit({ type: 'status', target: _this, status: line, }); } } }); executor(child, resolve, reject); }); }; BrowserStackTunnel.prototype._stop = function () { var _this = this; return new Promise(function (resolve) { var childProcess = _this._process; if (!childProcess) { resolve(undefined); return; } var exited = false; childProcess.once('exit', function (code) { exited = true; resolve(code == null ? undefined : code); }); util_1.kill(childProcess.pid); setTimeout(function () { if (!exited) { util_1.kill(childProcess.pid); } }, 5000); }); }; BrowserStackTunnel.prototype._normalizeEnvironment = function (environment) { var platformMap = { Windows: { '11': 'WINDOWS', '10': 'WINDOWS', '8.1': 'WIN8', '8': 'WIN8', '7': 'WINDOWS', XP: 'XP', }, 'OS X': 'MAC', }; var browserMap = { ie: 'internet explorer', }; var platform = platformMap[environment.os] || environment.os; if (typeof platform === 'object') { platform = platform[environment.os_version]; } var browserName = browserMap[environment.browser] || environment.browser; var version = environment.browser_version; return { platform: platform, platformName: environment.os, platformVersion: environment.os_version, browserName: browserName, browserVersion: version, version: environment.browser_version, descriptor: environment, intern: { platform: platform, browserName: browserName, version: version, }, }; }; return BrowserStackTunnel; }(Tunnel_1.default)); exports.default = BrowserStackTunnel; //# sourceMappingURL=BrowserStackTunnel.js.map