Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ docs/js/examples
docs/downloads
examples/shared/*.js
test/the-files-to-test.generated.js
sauce_connect.log*
4 changes: 3 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var browserifyTask = require('./grunt/tasks/browserify');
var populistTask = require('./grunt/tasks/populist');
var webdriverPhantomJSTask = require('./grunt/tasks/webdriver-phantomjs');
var webdriverJasmineTasks = require('./grunt/tasks/webdriver-jasmine');
var sauceTunnelTask = require('./grunt/tasks/sauce-tunnel');
var npmTask = require('./grunt/tasks/npm');
var releaseTasks = require('./grunt/tasks/release');

Expand Down Expand Up @@ -46,6 +47,8 @@ module.exports = function(grunt) {

grunt.registerMultiTask('populist', populistTask);

grunt.registerTask('sauce-tunnel', sauceTunnelTask);

grunt.registerMultiTask('webdriver-jasmine', webdriverJasmineTasks);

grunt.registerMultiTask('npm', npmTask);
Expand All @@ -71,7 +74,6 @@ module.exports = function(grunt) {
grunt.registerTask('build:min', ['jsx:release', 'version-check', 'browserify:min']);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also remove the obsolete parts from grunt/config/jsx/jsx.js?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

grunt.registerTask('build:addons-min', ['jsx:debug', 'browserify:addonsMin']);
grunt.registerTask('build:test', [
'jsx:jasmine',
'jsx:test',
'version-check',
'populist:test'
Expand Down
10 changes: 0 additions & 10 deletions grunt/config/jsx/jsx.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,6 @@ var debug = {
outputDir: "build/modules"
};

var jasmine = {
rootIDs: [
"all"
],
getConfig: getDebugConfig,
sourceDir: "vendor/jasmine",
outputDir: "build/jasmine"
};

var test = {
rootIDs: rootIDs.concat([
"test/all.js",
Expand Down Expand Up @@ -71,7 +62,6 @@ var release = {

module.exports = {
debug: debug,
jasmine: jasmine,
test: test,
release: release
};
40 changes: 18 additions & 22 deletions grunt/config/server.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,38 @@
var pxlgif = Buffer('R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==', 'base64');

module.exports = function(grunt){

function printMiddleware(req, res, next) {
if (req._parsedUrl.pathname != '/print') return next();
if (req.query.message.indexOf('ok') === 0){
grunt.log.ok(req.query.message);
} else if (req.query.message.indexOf('not ok') === 0){
grunt.log.error(req.query.message);
} else {
grunt[req.query.type || 'log'].writeln('[%s][%s]', req.headers['user-agent'], Date.now(), req.query.message);
}
res.end(pxlgif);
}

function testResultLoggerMiddleware(req, res, next) {
if (!(req.body && req.body.data)) return next();
grunt.log.writeln('[%s][%s]', req.headers['user-agent'], Date.now(), req.body.data);
if (!(req.method == 'POST' && req._parsedUrl.pathname.indexOf('/reportTestResults') === 0)) return next();
var logType = 'writeln';
var message = req.body;

if (req.body.type && req.body.message){
if (req.body.type == 'error') logType = 'error';
else if (req.body.message.indexOf('ok') === 0) logType = 'ok';
else if (req.body.message.indexOf('not ok') === 0) logType = 'error';
message = req.body.message;
}
if (typeof message != 'string') message = JSON.stringify(message, null, 2);
grunt.log[logType]('[%s][%s]', req.headers['user-agent'], Date.now(), message);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we figure out if grunt.log.writeln exists?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res.write('<!doctype html><meta charset=utf-8>');
res.end('Got it, thanks!');
}

return {
server: {
options: {
base: '.',
hostname: '*',
port: 9999,
middleware: function(connect, options) {

connect.logger.token('user-agent', function(req, res){ return req.headers['user-agent']; });
connect.logger.token('timestamp', function(req, res){ return Date.now(); });

return [
connect.query(),
printMiddleware,

connect.logger({format:'[:user-agent][:timestamp] :method :url', stream:grunt.verbose}),
connect.bodyParser(),
connect.json(),
testResultLoggerMiddleware,

connect.logger({format:'[:user-agent][:timestamp] :method :url', stream:grunt.verbose}),
connect.static(options.base),
connect.directory(options.base)
];
Expand Down
76 changes: 73 additions & 3 deletions grunt/config/webdriver-jasmine.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,83 @@ exports.local = {
remote: { protocol: 'http:', hostname: '127.0.0.1', port: 9515, path: '/' }
},
url: "http://127.0.0.1:9999/test/index.html",
onComplete: function(report){
var browser = this;
if (!report.passed){
onComplete: function(passed){
if (!passed){
grunt.fatal("tests failed");
}
},
onError: function(error){
grunt.fatal(error);
}
}

if (grunt.option('debug')) exports.local.url += '?debug=' + grunt.option('debug');


exports.saucelabs = {
webdriver: {
remote: {
/* https://github.com/admc/wd/blob/master/README.md#named-parameters */
user: process.env.SAUCE_USERNAME,
pwd: process.env.SAUCE_ACCESS_KEY,

protocol: 'http:',
hostname: 'ondemand.saucelabs.com',
port: '80',
path: '/wd/hub'
}
},
desiredCapabilities: {
"build": process.env.TRAVIS_BUILD_NUMBER || 'dev' + Date.now(),
"tunnel-identifier": process.env.TRAVIS_JOB_NUMBER || 'my awesome tunnel',
"browserName": "chrome"
},
url: exports.local.url,
onStart: function(browser){
grunt.log.writeln("Starting WebDriver Test. Watch results here: http://saucelabs.com/tests/" + browser.sessionID);
},
onComplete: exports.local.onComplete,
onError: exports.local.onError
}

/* https://saucelabs.com/docs/platforms */
exports.saucelabs_ios =
exports.saucelabs_ios6_1 = sauceItUp({ browserName: 'iphone', version: '6.1', platform:'OS X 10.8' });
exports.saucelabs_ios6 = sauceItUp({ browserName: 'iphone', version: '6', platform:'OS X 10.8' });
exports.saucelabs_ios5_1 = sauceItUp({ browserName: 'iphone', version: '5.1', platform:'OS X 10.8' });
exports.saucelabs_ios5 = sauceItUp({ browserName: 'iphone', version: '5', platform:'OS X 10.6' });
exports.saucelabs_ios4 = sauceItUp({ browserName: 'iphone', version: '4', platform:'OS X 10.6' });

exports.saucelabs_ipad =
exports.saucelabs_ipad6_1 = sauceItUp({ browserName: 'ipad', version: '6.1', platform:'OS X 10.8' });
exports.saucelabs_ipad6 = sauceItUp({ browserName: 'ipad', version: '6', platform:'OS X 10.8' });
exports.saucelabs_ipad5_1 = sauceItUp({ browserName: 'ipad', version: '5.1', platform:'OS X 10.8' });
exports.saucelabs_ipad5 = sauceItUp({ browserName: 'ipad', version: '5', platform:'OS X 10.6' });
exports.saucelabs_ipad4 = sauceItUp({ browserName: 'ipad', version: '4', platform:'OS X 10.6' });

exports.saucelabs_android = sauceItUp({ browserName: 'android', version: '4.0', platform:'Linux' });
exports.saucelabs_android_tablet = sauceItUp({ browserName: 'android', version: '4.0', platform:'Linux', 'device-type':'tablet' });

exports.saucelabs_safari = sauceItUp({ browserName: 'safari' });
exports.saucelabs_chrome = sauceItUp({ browserName: 'chrome' });
exports.saucelabs_firefox = sauceItUp({ browserName: 'firefox' });

exports.saucelabs_ie =
exports.saucelabs_ie8 = sauceItUp({ browserName: 'internet explorer', version: 8 });
exports.saucelabs_ie9 = sauceItUp({ browserName: 'internet explorer', version: 9 });
exports.saucelabs_ie10 = sauceItUp({ browserName: 'internet explorer', version: 10 });
exports.saucelabs_ie11 = sauceItUp({ browserName: 'internet explorer', version: 11, platform:'Windows 8.1' });


function sauceItUp(desiredCapabilities){
desiredCapabilities["build"] = exports.saucelabs.desiredCapabilities["build"];
desiredCapabilities["tunnel-identifier"] = exports.saucelabs.desiredCapabilities["tunnel-identifier"];
return {
webdriver: exports.saucelabs.webdriver,
url: exports.saucelabs.url,
onStart: exports.saucelabs.onStart,
onComplete: exports.saucelabs.onComplete,
onError: exports.saucelabs.onError,
desiredCapabilities: desiredCapabilities,
};
}
38 changes: 38 additions & 0 deletions grunt/tasks/sauce-tunnel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var grunt = require('grunt');
var SauceTunnel = require('sauce-tunnel');

module.exports = function(){
var task = this;
var config = task.data;
var shouldStayAliveForever = task.flags.keepalive;

var SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY;
if (!SAUCE_ACCESS_KEY) grunt.fatal('Requires the environment variable SAUCE_ACCESS_KEY to be set');

var SAUCE_USERNAME = process.env.SAUCE_USERNAME;
if (!SAUCE_USERNAME) grunt.fatal('Requires the environment variable SAUCE_USERNAME to be set');

var IDENTIFIER = process.env.TRAVIS_JOB_NUMBER || 'my awesome tunnel';

var taskCompletedSuccessfully = task.async();

var stunnel = new SauceTunnel(SAUCE_USERNAME, SAUCE_ACCESS_KEY, IDENTIFIER, /*tunneled*/true, /*tunnelTimeout*/5);
process.on('exit', stunnel.stop.bind(stunnel, function(){}));

stunnel.on('log:error', grunt.log.error.bind(grunt.log));
stunnel.on('log:writeln', grunt.log.writeln.bind(grunt.log));

stunnel.on('verbose:ok', grunt.verbose.ok.bind(grunt.verbose));
stunnel.on('verbose:error', grunt.verbose.error.bind(grunt.verbose));
stunnel.on('verbose:debug', grunt.verbose.debug.bind(grunt.verbose));
stunnel.on('verbose:writeln', grunt.verbose.writeln.bind(grunt.verbose));

stunnel.openTunnel(function(isOpen){
if (shouldStayAliveForever && isOpen){
grunt.verbose.writeln('Keeping the sauce-tunnel open forever because you used the keepalive flag `' + task.nameArgs + '`');
return;
}
grunt.verbose.writeln('To keep the sauce-tunnel open forever, use the grunt task `' + task.nameArgs + ':keepalive`');
taskCompletedSuccessfully(isOpen);
});
};
47 changes: 37 additions & 10 deletions grunt/tasks/webdriver-jasmine.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ var wd = require('wd');
module.exports = function(){
var config = this.data;
var taskSucceeded = this.async();
grunt.verbose.write('webdriver remote', JSON.stringify(config.webdriver.remote));

var desiredCapabilities = {};
if (config.desiredCapabilities) Object.keys(config.desiredCapabilities).forEach(function(key){
if (config.desiredCapabilities[key] === undefined) return;
desiredCapabilities[key] = config.desiredCapabilities[key];
});
grunt.verbose.writeln("desiredCapabilities", JSON.stringify(desiredCapabilities));

var browser = wd.promiseChainRemote(config.webdriver.remote);

browser.on('status', function(info) {
Expand All @@ -15,30 +22,50 @@ module.exports = function(){
grunt.verbose.writeln(' > ' + meth, path, data || '');
});

var results = null;

// browser._debugPromise();
browser
.init(config.browser || {})
.init(desiredCapabilities)
.then(config.onStart && config.onStart.bind(config, browser))
.get(config.url)
.then(function(){return browser;})
.then(getJSReport)
.then(config.onComplete && config.onComplete.bind(browser), config.onError && config.onError.bind(browser))
.fail(grunt.verbose.writeln.bind(grunt.verbose))
.fin(function(){
.then(function(data){ results = data; })
.fail(function(error){
grunt.log.error(error);
return browser
.eval('document.documentElement.innerText || document.documentElement.textContent')
.then(grunt.verbose.writeln.bind(grunt.verbose))
.then(function(){throw error})
;
})
.finally(function(){
if (grunt.option('webdriver-keep-open')) return;
grunt.verbose.writeln('Closing the browser window. To keep it open, pass the --webdriver-keep-open flag to grunt.');
return browser.quit();
})
.done(
taskSucceeded.bind(null,true),
taskSucceeded.bind(null,false)
function(){
if (config.onComplete) config.onComplete(results);
taskSucceeded(true);
},
function(error){
if (config.onError) config.onError(error);
taskSucceeded(false);
}
)
;
}

function getJSReport(browser){
return browser
.waitForCondition("typeof window.jasmine != 'undefined'", 500)
.waitForCondition("typeof window.jasmine != 'undefined'", 5e3)
.fail(function(error){
throw Error("The test page didn't load properly. " + error);
})
.waitForCondition("typeof window.jasmine.getJSReport != 'undefined'", 10e3)
.waitForCondition("window.testImageURL.running <= 0", 5e3)
.eval("jasmine.getJSReport()")
.waitForCondition("window.postDataToURL.running <= 0", 30e3)
.eval("jasmine.getJSReport().passed")
;
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@
"jasmine-tapreporter": "~0.2.2",
"grunt-contrib-connect": "~0.5.0",
"es5-shim": "~2.1.0",
"wd": "~0.2.2"
"wd": "~0.2.2",
"sauce-tunnel": "~1.1.0"
},
"engines": {
"node": ">=0.10.0"
Expand Down
Loading