Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

grunt-saucelabs

Package Overview
Dependencies
Maintainers
3
Versions
56
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grunt-saucelabs - npm Package Compare versions

Comparing version 4.0.3 to 4.0.4

.gitmodules

30

Gruntfile.js

@@ -50,2 +50,30 @@ module.exports = function(grunt) {

'saucelabs-yui': {
all: {
//username: '',
//key: '',
options: {
urls: ['http://127.0.0.1:9999/yui/index.html'],
tunnelTimeout: 5,
build: process.env.TRAVIS_JOB_ID,
concurrency: 3,
browsers: browsers,
testname: "yui tests"
}
}
},
'saucelabs-mocha': {
all: {
//username: '',
//key: '',
options: {
urls: ['http://127.0.0.1:9999/mocha/test/browser/opts.html'],
tunnelTimeout: 5,
build: process.env.TRAVIS_JOB_ID,
concurrency: 3,
browsers: browsers,
testname: "mocha tests"
}
}
},
'saucelabs-qunit': {

@@ -115,4 +143,4 @@ all: {

grunt.registerTask('test', ['connect', 'saucelabs-qunit', 'saucelabs-jasmine']);
grunt.registerTask('test', ['connect', 'saucelabs-qunit', 'saucelabs-jasmine', 'saucelabs-yui', 'saucelabs-mocha']);
grunt.registerTask('default', ['jshint', 'test', 'publish']);
};

2

package.json
{
"name": "grunt-saucelabs",
"description": "Grunt task running tests using Sauce Labs. Supports Qunit and Jasmine tests",
"version": "4.0.3",
"version": "4.0.4",
"homepage": "https://github.com/axemclion/grunt-saucelabs",

@@ -6,0 +6,0 @@ "author": {

@@ -7,6 +7,10 @@ grunt-saucelabs

A Grunt task for running qunit and jasmine tests using Sauce Labs' Cloudified Browsers.
[![Selenium Test Status](https://saucelabs.com/browser-matrix/grunt-sauce.svg)](https://saucelabs.com/u/grunt-sauce)
A Grunt task for running QUnit, Jasmine, Mocha and YUI tests using Sauce Labs' Cloudified Browsers.
[Grunt](http://gruntjs.com/) is a task-based command line build tool for JavaScript projects, based on nodejs.
[QUnit](http://qunitjs.com/) is a powerful, easy-to-use JavaScript unit test suite used by the jQuery, jQuery UI and jQuery Mobile projects and is capable of testing any generic JavaScript code, including itself!
[Mocha](http://visionmedia.github.io/mocha/) is a JavaScript test framework for running serial asynchronous tests.
[YUI Test](http://developer.yahoo.com/yui/yuitest/) is a browser-based testing framework from Yahoo!.
[Sauce Labs](https://saucelabs.com/) offers browser environments on the cloud for testing code.

@@ -19,3 +23,3 @@

The task also uses [Sauce Connect](https://saucelabs.com/docs/connect) to establish a tunnel between Sauce Labs browsers and the machine running Grunt to load local pages. This is typically useful for testing pages on localhost that are not publically accessible on the internet.
The `saucelabs-jasmine` runs jasmine tests in the Sauce Labs browser. The `saucelabs-jasmine` task requires `jasmine-1.3.0`.
The `saucelabs-jasmine` runs [Jasmine](http://pivotal.github.io/jasmine/) tests in the Sauce Labs browser. The `saucelabs-jasmine` task requires `jasmine-1.3.0`. There are also `saucelabs-mocha` and `saucelabs-yui` tasks that let you run your Mocha and YUI tests on Sauce Labs cloudified browser environment.

@@ -73,3 +77,3 @@ Usage

The configuration of `saucelabs-jasmine` are exactly the same.
The configuration of `saucelabs-jasmine`, `saucelabs-mocha`, `saucelabs-yui` are exactly the same.
Note the options object inside a grunt target. This was introduced in grunt-saucelabs-* version 4.0.0 to be compatiable with grunt@0.4.0

@@ -95,2 +99,19 @@

Test results details with Jasmine
---------------------------------
You can make Job Details pages more infromative on Sauce by providing more data with each test. You will get info about each test run inside your suite directly on Sauce pages.
[![Jasmine detailed results](https://saucelabs.com/images/front-tests/jasmine.png)](https://saucelabs.com/docs/javascript-unit-tests-integration)
You can do that by using [Jasmine JS Reporter](https://github.com/detro/jasmine-jsreporter) that will let `saucelabs-jasmine` task provide in-depth data about each test as a JSON object.
All you need to do is to include the new jasmine-jsreporter reporter to the page running Jasmine tests by adding new script in header:
```html
<script src="path/to/jasmine-jsreporter.js" type="text/javascript"></script>
```
and telling Jasmine to use it:
```javascript
jasmineEnv.addReporter(new jasmine.JSReporter());
````
Examples

@@ -97,0 +118,0 @@ --------

@@ -417,2 +417,34 @@ module.exports = function(grunt) {

TestRunner.prototype.yuiSaucify = function(results) {
var out = {'custom-data': {}};
_.each(results, function (result, i) {
if ( result !== null) {
var keyName = i === 0 ? 'yui' : 'yui' + i;
out['custom-data'][keyName] = {
failed: result.failed,
passed: result.passed,
total: result.total,
runtime: result.duration
};
}
});
return out;
};
TestRunner.prototype.mochaSaucify = function(results) {
var out = {'custom-data': {}};
_.each(results, function (result, i) {
if ( result !== null) {
var keyName = i === 0 ? 'mocha' : 'mocha' + i;
out['custom-data'][keyName] = {
failed: result[2],
passed: result[1],
total: result[4],
runtime: +result[3] * 1000
};
}
});
return out;
};
TestRunner.prototype.qunitRunner = function(driver, cfg, testTimeout, testInterval, testReadyTimeout, detailedError, callback) {

@@ -493,2 +525,141 @@ var testResult = "qunit-testresult";

TestRunner.prototype.yuiRunner = function(driver, cfg, testTimeout, testInterval, testReadyTimeout, detailedError, callback) {
grunt.verbose.writeln("[%s] Starting YUI tests for page", cfg.prefix);
driver.waitForConditionInBrowser("YUI.YUITest.Runner.getResults() !=== null", testReadyTimeout, function() {
grunt.verbose.writeln("[%s] Test results ready, fetching", cfg.prefix);
driver.safeEval("YUI.YUITest.Runner.getResults()", function(err, json) {
if (err) {
grunt.log.error("[%s] Could not read test result for %s", cfg.prefix, err, driver.page);
grunt.log.error("[%s] More details at http://saucelabs.com/tests/%s", cfg.prefix, driver.page);
callback(false);
return;
}
grunt.verbose.writeln("[%s] Fetched test results", cfg.prefix);
var showDetailedError = function(cb) {
var outputFailures = function(obj) {
_.forOwn(obj, function (val, key, iobj) {
if (_.isObject(val)) {
return outputFailures(val);
}
if (val === 'fail' && key === 'result') {
grunt.log.error("\n%s", iobj.message.replace(/\n/g, ' '));
}
});
};
outputFailures(json);
cb();
};
if (typeof json !== 'object'){
grunt.log.error('Error - Could not read test run results %s', typeof text);
callback(false);
return;
}
// Test is now completed, so parse the results
grunt.log.subhead('\nTested %s', driver.page);
grunt.log.writeln('Environment: %s', cfg.prefix);
if (err) {
grunt.log.error("Could not see test results: %s", err.replace(/\n/g, ' '));
callback(false);
return;
}
if (json.failed !== 0) {
return showDetailedError(function () { callback(false, json); });
}
grunt.log.ok("Result: total: %s passed: %s failed: %s", json.total, json.passed, json.failed);
grunt.log.writeln("Test Video: http://saucelabs.com/tests/%s", driver.sessionID);
callback(true, json);
});
});
};
TestRunner.prototype.mochaRunner = function(driver, cfg, testTimeout, testInterval, testReadyTimeout, detailedError, callback) {
var testResult = "mocha-stats",
resultRegexp = /passes: (\d*)failures: (\d*)duration: ([\d,.]*)s/,
currentState = null,
retryCount = 0;
grunt.verbose.writeln("[%s] Starting mocha tests for page", cfg.prefix);
driver.waitForElementById(testResult, testReadyTimeout, function() {
grunt.verbose.writeln("[%s] Test div found, fetching the test results elements", cfg.prefix);
driver.elementById(testResult, function(err, el) {
if (err) {
grunt.log.error("[%s] Could not read test result for %s", cfg.prefix, err, driver.page);
grunt.log.error("[%s] More details at http://saucelabs.com/tests/%s", cfg.prefix, driver.page);
callback(false);
return;
}
grunt.verbose.writeln("[%s] Fetched test result element, waiting for text inside it show complete status", cfg.prefix);
var showDetailedError = function(cb) {
driver.elementById(testResult, function(err, detailEl) {
driver.text(detailEl, function(err, detailText) {
grunt.log.error("\n%s", detailText);
cb();
});
});
};
var fetchResults = function(cb, status) {
cb(status, err || currentState);
};
driver.safeEval("mocha.suite.total()", function(err, totalResults) {
(function isCompleted() {
driver.text(el, function(err, text) {
if (typeof text !== 'string'){
grunt.log.error('Error - Could not read text to check if this was completed %s', typeof text);
callback(false);
return;
}
currentState = text.match(resultRegexp);
currentState[1] = parseInt(currentState[1], 10);
currentState[2] = parseInt(currentState[2], 10);
currentState.push(totalResults);
if ((!currentState || currentState[1] + currentState[2] < totalResults) && ++retryCount * testInterval <= testTimeout) {
grunt.verbose.writeln("[%s] %s. Still running, Time passed - %s of %s milliseconds", cfg.prefix, retryCount, testInterval * retryCount, testTimeout);
setTimeout(isCompleted, testInterval);
return;
}
// Test is now completed, so parse the results
grunt.log.subhead('\nTested %s', driver.page);
grunt.log.writeln('Environment: %s', cfg.prefix);
if (err) {
grunt.log.error("Could not see test results: %s", err.replace(/\n/g, ' '));
fetchResults(callback, false);
return;
}
if (retryCount * testInterval > testTimeout) {
grunt.log.error("Timeout, waited for more than %s milliseconds", testTimeout);
fetchResults(callback, false);
return;
}
if (+currentState[2] !== 0) {
if (detailedError) {
return showDetailedError(function() {
fetchResults(callback, false);
});
}
fetchResults(callback, false);
} else {
grunt.log.ok("Result: %s", text.replace(/\n/g, ' '));
fetchResults(callback, true);
}
grunt.log.writeln("Test Video: http://saucelabs.com/tests/%s", driver.sessionID);
});
}());
});
});
});
};
var defaultsObj = {

@@ -578,2 +749,50 @@ username: process.env.SAUCE_USERNAME,

});
grunt.registerMultiTask('saucelabs-yui', 'Run YUI test cases using Sauce Labs browsers', function() {
var done = this.async(),
arg = defaults(this.options(defaultsObj));
var tunnel = new SauceTunnel(arg.username, arg.key, arg.identifier, arg.tunneled, arg.tunnelTimeout);
grunt.log.writeln("=> Connecting to Saucelabs ...");
if (this.tunneled) {
grunt.verbose.writeln("=> Starting Tunnel to Sauce Labs".inverse.bold);
}
tunnel.start(function(isCreated) {
if (!isCreated) {
done(false);
return;
}
grunt.log.ok("Connected to Saucelabs");
var test = new TestRunner(arg.username, arg.key);
test.forEachBrowser(arg.browsers, test.yuiRunner, test.yuiSaucify, arg.concurrency, arg.onTestComplete).testPages(arg.pages, arg.testTimeout, arg.testInterval, arg.testReadyTimeout, arg.detailedError, function(status) {
grunt.log[status ? 'ok' : 'error']("All tests completed with status %s", status);
tunnel.stop(function() {
done(status);
});
});
});
});
grunt.registerMultiTask('saucelabs-mocha', 'Run Mocha test cases using Sauce Labs browsers', function() {
var done = this.async(),
arg = defaults(this.options(defaultsObj));
var tunnel = new SauceTunnel(arg.username, arg.key, arg.identifier, arg.tunneled, arg.tunnelTimeout);
grunt.log.writeln("=> Connecting to Saucelabs ...");
if (this.tunneled) {
grunt.verbose.writeln("=> Starting Tunnel to Sauce Labs".inverse.bold);
}
tunnel.start(function(isCreated) {
if (!isCreated) {
done(false);
return;
}
grunt.log.ok("Connected to Saucelabs");
var test = new TestRunner(arg.username, arg.key);
test.forEachBrowser(arg.browsers, test.mochaRunner, test.mochaSaucify, arg.concurrency, arg.onTestComplete).testPages(arg.pages, arg.testTimeout, arg.testInterval, arg.testReadyTimeout, arg.detailedError, function(status) {
grunt.log[status ? 'ok' : 'error']("All tests completed with status %s", status);
tunnel.stop(function() {
done(status);
});
});
});
});
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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