Socket
Socket
Sign inDemoInstall

karma-sauce-launcher

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

karma-sauce-launcher - npm Package Compare versions

Comparing version 0.1.5 to 0.2.0

lib/sauce_connect.js

248

index.js

@@ -1,244 +0,16 @@

// TODO(vojta):
// - add concrete browsers
// - more config (+ global config)
var SauceConnect = require('./lib/sauce_connect');
var SauceLauncher = require('./lib/sauce_launcher');
var SauceReporter = require('./lib/sauce_reporter');
var q = require('q');
var wd = require('wd');
var launchSauceConnect = require('sauce-connect-launcher');
// SauceLabs is a wrapper around the Sauce Labs REST API
var SauceLabs = require('saucelabs');
// We keep a mapping from Karma launch IDs to Sauce job IDs here, to report the pass/fail results.
// We also keep the Sauce credentials here - theoretically different credentials can be used for
// different browsers in the same session.
var jobMapping = {};
var SauceConnect = function(emitter, logger) {
var log = logger.create('launcher.sauce');
var alreadyRunningDefered;
var alreadyRunningProces;
this.start = function(username, accessKey, tunnelIdentifier, done) {
var options = {
username: username,
accessKey: accessKey,
verbose: false,
logfile: null,
logger: log.debug.bind(log),
no_progress: false,
tunnelIdentifier: tunnelIdentifier
};
// TODO(vojta): if different username/accessKey, start a new process
if (alreadyRunningDefered) {
log.debug('Sauce Connect is already running or starting');
return alreadyRunningDefered.promise;
}
alreadyRunningDefered = q.defer();
launchSauceConnect(options, function(err, p) {
if (err) {
return alreadyRunningDefered.reject(err);
}
alreadyRunningProces = p;
alreadyRunningDefered.resolve();
});
return alreadyRunningDefered.promise;
};
emitter.on('exit', function(done) {
if (alreadyRunningProces) {
log.info('Shutting down Sauce Connect');
alreadyRunningProces.close(done);
alreadyRunningProces = null;
} else {
done();
}
});
};
var SauceLabsBrowser = function(id, args, sauceConnect, /* config.sauceLabs */ config, logger, emitter, helper) {
config = config || {};
var username = process.env.SAUCE_USERNAME || args.username || config.username;
var accessKey = process.env.SAUCE_ACCESS_KEY || args.accessKey || config.accessKey;
var tunnelIdentifier = args.tunnelIdentifier || config.tunnelIdentifier;
var browserName = args.browserName + (args.version ? ' ' + args.version : '') +
(args.platform ? ' (' + args.platform + ')' : '') + ' on SauceLabs';
var startConnect = config.startConnect !== false;
var log = logger.create('launcher.sauce');
var self = this;
var driver;
var captured = false;
if (startConnect && !tunnelIdentifier) {
tunnelIdentifier = 'karma' + Math.round(new Date().getTime() / 1000);
}
this.id = id;
this.name = browserName;
var pendingHeartBeat;
var heartbeat = function() {
pendingHeartBeat = setTimeout(function() {
log.debug('Heartbeat to Sauce Labs - fetching title');
driver.title();
heartbeat();
}, 60000);
};
var formatSauceError = function(err) {
return err.message + '\n ' + err.data.split('\n').shift();
};
var start = function(url) {
var options = helper.merge(config.options, args, {
browserName: args.browserName,
version: args.version || '',
platform: args.platform || 'ANY',
tags: args.tags || config.tags || [],
name: args.testName || config.testName || 'Karma test',
'tunnel-identifier': tunnelIdentifier,
'record-video': args.recordVideo || config.recordVideo || false,
'record-screenshots': args.recordScreenshots || config.recordScreenshots || true,
'build': args.build || config.build || process.env.TRAVIS_BUILD_NUMBER ||
process.env.BUILD_NUMBER || process.env.BUILD_TAG ||
process.env.CIRCLE_BUILD_NUM || null,
'device-orientation': args.deviceOrientation || null
});
// Adding any other option that was specified in args, but not consumed from above
// Useful for supplying chromeOptions, firefoxProfile, etc.
for (var key in args){
if (typeof options[key] === 'undefined') {
options[key] = args[key];
}
}
url = url + '?id=' + id;
driver = wd.remote('ondemand.saucelabs.com', 80, username, accessKey);
driver.init(options, function(err, jobId) {
if (err) {
log.error('Can not start %s\n %s', browserName, formatSauceError(err));
return emitter.emit('browser_process_failure', self);
}
// Record the job details, so we can access it later with the reporter
jobMapping[id] = {
jobId: jobId,
credentials: {
username: username,
password: accessKey
}
};
log.info('%s session at https://saucelabs.com/tests/%s', browserName, driver.sessionID);
log.debug('WebDriver channel instantiated, opening ' + url);
driver.get(url, heartbeat);
});
};
this.start = function(url) {
if (startConnect) {
sauceConnect.start(username, accessKey, tunnelIdentifier).then(function() {
start(url);
}, function(err) {
log.error('Can not start %s\n Failed to start Sauce Connect:\n %s', browserName, err.message);
emitter.emit('browser_process_failure', self);
});
} else {
start(url);
}
};
this.kill = function(done) {
if (!driver) {
return process.nextTick(done);
}
clearTimeout(pendingHeartBeat);
log.debug('Shutting down Sauce Labs driver');
// workaround - navigate to other page to avoid re-connection
driver.get('about:blank', function() {
driver.quit(done);
});
};
this.markCaptured = function() {
captured = true;
};
this.isCaptured = function() {
return captured;
};
this.toString = function() {
return this.name;
};
};
var SauceLabsReporter = function(baseReporterDecorator, emitter, logger) {
var log = logger.create('reporter.sauce');
baseReporterDecorator(this);
var pendingUpdates = 0;
var updatesFinished = function() {};
// We're only interested in the final results per browser
this.onBrowserComplete = function(browser) {
var result = browser.lastResult;
// browser.launchId was used until v0.10.2, but changed to just browser.id in v0.11.0
var browserId = browser.launchId || browser.id;
if(browserId in jobMapping) {
var jobDetails = jobMapping[browserId];
var sauceApi = new SauceLabs(jobDetails.credentials);
// We record pass/fail status, as well as the full results in "custom-data".
var payload = {
passed: !(result.failed || result.error),
'custom-data': result
};
pendingUpdates++;
sauceApi.updateJob(jobDetails.jobId, payload, function(err) {
pendingUpdates--;
if (err) {
log.error('Failed record pass/fail status: %s', err.error);
}
if (pendingUpdates == 0) {
updatesFinished();
}
});
}
};
// Wait until all updates have been pushed to SauceLabs
emitter.on('exit', function(done) {
if (pendingUpdates) {
updatesFinished = done;
} else {
done();
}
});
};
SauceLabsReporter.$inject = ['baseReporterDecorator', 'emitter', 'logger'];
// PUBLISH DI MODULE
module.exports = {
'sauceConnect': ['type', SauceConnect],
'launcher:SauceLabs': ['type', SauceLabsBrowser],
'reporter:saucelabs': ['type', SauceLabsReporter]
'launcher:SauceLabs': ['type', SauceLauncher],
'reporter:saucelabs': ['type', SauceReporter],
// We keep a mapping from Karma launch IDs to Sauce job IDs here, to report the pass/fail results.
// We also keep the Sauce credentials here - theoretically different credentials can be used for
// different browsers in the same session.
'sauce:jobMapping': ['value', {}]
};
{
"name": "karma-sauce-launcher",
"version": "0.1.5",
"version": "0.2.0",
"description": "A Karma plugin. Launch any browser on SauceLabs!",

@@ -22,4 +22,4 @@ "main": "index.js",

"dependencies": {
"wd": "~0.1.5",
"sauce-connect-launcher": "~0.1.10",
"wd": "~0.2.8",
"sauce-connect-launcher": "~0.2.2",
"q": "~0.9.6",

@@ -29,3 +29,3 @@ "saucelabs": "~0.1.0"

"peerDependencies": {
"karma": ">=0.9"
"karma": ">=0.11.11"
},

@@ -32,0 +32,0 @@ "license": "MIT",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc