diff --git a/.gitignore b/.gitignore index fce7d1d993be4..e69b58bd049c0 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,4 @@ docs/js/live_editor.js docs/js/examples docs/downloads examples/shared/*.js - +test/the-files-to-test.generated.js diff --git a/.travis.yml b/.travis.yml index 1a40ce3cf6cae..0f00ae082cb9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,3 +13,5 @@ env: - secure: qPvsJ46XzGrdIuPA70b55xQNGF8jcK7N1LN5CCQYYocXLa+fBrl+fTE77QvehOPhqwJXcj6kOxI+sY0KrVwV7gmq2XY2HZGWUSCxTN0SZlNIzqPA80Y7G/yOjA4PUt8LKgP+8tptyhTAY56qf+hgW8BoLiKOdztYF2p+3zXOLuA= # SECRET_TOKEN - secure: dkpPW+VnoqC/okhRdV90m36NcyBFhcwEKL3bNFExAwi0dXnFao8RoFlvnwiPlA23h2faROkMIetXlti6Aju08BgUFV+f9aL6vLyU7gUent4Nd3413zf2fwDtXIWIETg6uLnOpSykGKgCAT/hY3Q2oPLqOoY0OxfgnbqwxkxljrE= + - secure: eHMg4yQWJ+5zFxNcjVwpdpcbZCQMaSByqJy0wwQ2XOOMItdCvSfO/fa+mYoVND/9Orsi5kvXC9tx4sYHyth5hLrvO+bghYjiayrbxYYrxso6G/aU8Pttc7s/qk3I4zadLlua1kGy2TauByxS6nt9nUDe0FDaJKA9k1QXVlpq5Ac= + - secure: v65jUPPNBvJg1xhj4cY7wMKinCESUseHsW1d2gp68SluFHHyjWZOvXYXZdABqB/1uNmQxjbUkwkdSNAOn5k7ppjRcRnlAH2uu1xDqXrGp6cW4MfNPchrAe+FcUMtse/3THGJj8SZ9IQWIl+BHv4XASQ7FwqCR8cwlOfhsqdfch8= diff --git a/Gruntfile.js b/Gruntfile.js index 6ecc654e32cb3..c46d9a6ba4475 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -4,7 +4,8 @@ var exec = require('child_process').exec; var jsxTask = require('./grunt/tasks/jsx'); var browserifyTask = require('./grunt/tasks/browserify'); var populistTask = require('./grunt/tasks/populist'); -var phantomTask = require('./grunt/tasks/phantom'); +var webdriverPhantomJSTask = require('./grunt/tasks/webdriver-phantomjs'); +var webdriverJasmineTasks = require('./grunt/tasks/webdriver-jasmine'); var npmTask = require('./grunt/tasks/npm'); var releaseTasks = require('./grunt/tasks/release'); @@ -16,7 +17,8 @@ module.exports = function(grunt) { jsx: require('./grunt/config/jsx/jsx'), browserify: require('./grunt/config/browserify'), populist: require('./grunt/config/populist'), - phantom: require('./grunt/config/phantom'), + connect: require('./grunt/config/server')(grunt), + "webdriver-jasmine": require('./grunt/config/webdriver-jasmine.js'), npm: require('./grunt/config/npm'), clean: ['./build', './*.gem', './docs/_site', './examples/shared/*.js'], jshint: require('./grunt/config/jshint'), @@ -25,11 +27,12 @@ module.exports = function(grunt) { grunt.config.set('compress', require('./grunt/config/compress')); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-compare-size'); - grunt.loadNpmTasks('grunt-contrib-compress'); + Object.keys(grunt.file.readJSON('package.json').devDependencies) + .filter(function(npmTaskName){ return npmTaskName.indexOf('grunt-') === 0;}) + .forEach(function(npmTaskName){ + grunt.loadNpmTasks(npmTaskName); + }) + ; // Alias 'jshint' to 'lint' to better match the workflow we know grunt.registerTask('lint', ['jshint']); @@ -42,7 +45,7 @@ module.exports = function(grunt) { grunt.registerMultiTask('populist', populistTask); - grunt.registerMultiTask('phantom', phantomTask); + grunt.registerMultiTask('webdriver-jasmine', webdriverJasmineTasks); grunt.registerMultiTask('npm', npmTask); @@ -70,11 +73,17 @@ module.exports = function(grunt) { 'jsx:jasmine', 'jsx:test', 'version-check', - 'populist:jasmine', 'populist:test' ]); - grunt.registerTask('test', ['build:test', 'build:basic', 'phantom:run']); + grunt.registerTask('webdriver-phantomjs', webdriverPhantomJSTask); + + grunt.registerTask('test:webdriver:phantomjs', [ + 'connect', + 'webdriver-phantomjs', + 'webdriver-jasmine:local' + ]); + grunt.registerTask('test', ['build:test', 'build:basic', 'test:webdriver:phantomjs']); grunt.registerTask('npm:test', ['build', 'npm:pack']); // Optimized build task that does all of our builds. The subtasks will be run diff --git a/grunt/config/phantom.js b/grunt/config/phantom.js deleted file mode 100644 index 36cbc0f3ded11..0000000000000 --- a/grunt/config/phantom.js +++ /dev/null @@ -1,11 +0,0 @@ -var grunt = require("grunt"); - -exports.run = { - port: 8080, - harness: "test/phantom-harness.js", - // Run `grunt test --debug` to enable in-browser testing. - debug: !!grunt.option("debug"), - tests: [ - "**/__tests__/*-test.js" - ] -}; diff --git a/grunt/config/server.js b/grunt/config/server.js new file mode 100644 index 0000000000000..cfa4506dcf7e8 --- /dev/null +++ b/grunt/config/server.js @@ -0,0 +1,47 @@ +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); + 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(), + testResultLoggerMiddleware, + + connect.static(options.base), + connect.directory(options.base) + ]; + }, + } + } + } +} diff --git a/grunt/config/webdriver-jasmine.js b/grunt/config/webdriver-jasmine.js new file mode 100644 index 0000000000000..1b3a58b4a3876 --- /dev/null +++ b/grunt/config/webdriver-jasmine.js @@ -0,0 +1,18 @@ +var grunt = require('grunt'); + + +exports.local = { + webdriver: { + 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){ + grunt.fatal("tests failed"); + } + }, + onError: function(error){ + grunt.fatal(error); + } +} diff --git a/grunt/tasks/phantom.js b/grunt/tasks/phantom.js deleted file mode 100644 index d5c66eb2589a8..0000000000000 --- a/grunt/tasks/phantom.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict'; - -var assert = require("assert"); -var grunt = require("grunt"); -var spawn = grunt.util.spawn; -var semver = require("semver"); -var MIN_VERSION = "1.9.0"; -var phantomjs = require("phantomjs").path; - -function checkVersion(error, result, code) { - if (error) { - throw error; - } - assert.strictEqual(code, 0); - - var version = result.stdout; - - assert.ok( - semver.valid(version), - "Invalid PhantomJS version: " + version - ); - - assert.ok( - semver.gte(version, MIN_VERSION), - "PhantomJS v" + version + " too old; need to install " + - "v" + MIN_VERSION + " or higher." - ); -} - -function run(config, done) { - var args = [ - config.harness, - "--port", config.port - ]; - - if (config.debug) { - args.push("--debug"); - } - - args.push("--tests"); - grunt.file.expand({ - nonull: true, - cwd: "src" - }, config.tests || []).forEach(function(file) { - args.push(file.replace(/\.js$/i, "")); - }); - - var child = spawn({ - cmd: phantomjs, - args: args - }, done); - - child.stdout.pipe(process.stdout); - child.stderr.pipe(process.stderr); -} - -module.exports = function() { - var config = this.data; - var done = this.async(); - - spawn({ - cmd: phantomjs, - args: ["--version"] - }, function(error, result, code) { - checkVersion(error, result, code); - run(config, done); - }); -}; diff --git a/grunt/tasks/populist.js b/grunt/tasks/populist.js index b9b848bf884e4..eba314d91e3ef 100644 --- a/grunt/tasks/populist.js +++ b/grunt/tasks/populist.js @@ -1,11 +1,19 @@ 'use strict'; var grunt = require('grunt'); +var fs = require('fs') module.exports = function() { var config = this.data; var done = this.async(); + var theFilesToTestScript = fs.createWriteStream(__dirname + '/../../test/the-files-to-test.generated.js'); + theFilesToTestScript.write('// Generated by '); + theFilesToTestScript.write(JSON.stringify(__filename.split(/(?=grunt)/)[1])); + theFilesToTestScript.write(' at '); + theFilesToTestScript.write(JSON.stringify(new Date())); + theFilesToTestScript.write('\n\n'); + // create the bundle we'll work with var args = config.args; @@ -15,7 +23,9 @@ module.exports = function() { nonull: true, // Keep IDs that don't expand to anything. cwd: config.rootDirectory }, requires).forEach(function(name) { - args.push(name.replace(/\.js$/i, "")); + name = name.replace(/\.js$/i, ""); + args.push(name); + theFilesToTestScript.write('harness.enableTest(' + JSON.stringify(name) + ');\n'); }); require("populist").buildP({ @@ -23,6 +33,7 @@ module.exports = function() { args: args }).then(function(output) { grunt.file.write(config.outfile, output); + theFilesToTestScript.end(); done(); }); }; diff --git a/grunt/tasks/webdriver-jasmine.js b/grunt/tasks/webdriver-jasmine.js new file mode 100644 index 0000000000000..bd998dfcb7787 --- /dev/null +++ b/grunt/tasks/webdriver-jasmine.js @@ -0,0 +1,44 @@ +var grunt = require("grunt"); +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 browser = wd.promiseChainRemote(config.webdriver.remote); + + browser.on('status', function(info) { + grunt.verbose.writeln(info); + }); + + browser.on('command', function(meth, path, data) { + grunt.verbose.writeln(' > ' + meth, path, data || ''); + }); + + browser + .init(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(){ + 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 getJSReport(browser){ + return browser + .waitForCondition("typeof window.jasmine != 'undefined'", 500) + .waitForCondition("typeof window.jasmine.getJSReport != 'undefined'", 10e3) + .waitForCondition("window.testImageURL.running <= 0", 5e3) + .eval("jasmine.getJSReport()") + ; +} diff --git a/grunt/tasks/webdriver-phantomjs.js b/grunt/tasks/webdriver-phantomjs.js new file mode 100644 index 0000000000000..0f841b633e33e --- /dev/null +++ b/grunt/tasks/webdriver-phantomjs.js @@ -0,0 +1,37 @@ +var grunt = require('grunt'); + +module.exports = function(){ + var onReadyCallback = this.async(); + + var phantomjs = require("phantomjs").path; + var child_process = require('child_process'); + var config = this.data || {}; + + var args = ["--webdriver=" + (config.port || 9515)]; + grunt.verbose.writeln('phantomjs START path:%s args:%s', phantomjs, args); + + var child = child_process.spawn(phantomjs, args); + process.on('exit', function() { + child.kill(); + }); + + child.on('error', function(error) { + grunt.verbose.writeln('phantomjs ERROR'); + grunt.fatal(error); + }); + child.on('exit', function(code) { + grunt.verbose.writeln('phantomjs END'); + if (code) grunt.fatal('phantomjs FAIL'); + }); + + function verboseWrite(chunk) { + if (onReadyCallback && chunk.toString().indexOf('running on port') != -1) { + grunt.verbose.writeln('phantomjs STARTED'); + onReadyCallback(); + onReadyCallback = null; + } + grunt.verbose.write(chunk); + } + child.stdout.on('data', verboseWrite); + child.stderr.on('data', verboseWrite); +} diff --git a/package.json b/package.json index e86eef0a15df5..7cf8992686cf8 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "grunt-contrib-copy": "~0.4.1", "grunt-contrib-jshint": "~0.6.0", "optimist": "~0.6.0", - "phantomjs": "~1.9.1-4", + "phantomjs": "~1.9", "recast": "~0.4.16", "semver": "~2.1.0", "uglify-js": "~2.4.0", @@ -56,7 +56,11 @@ "grunt-compare-size": "~0.4.0", "gzip-js": "~0.3.2", "tmp": "~0.0.18", - "grunt-contrib-compress": "~0.5.1" + "grunt-contrib-compress": "~0.5.1", + "jasmine-tapreporter": "~0.2.2", + "grunt-contrib-connect": "~0.5.0", + "es5-shim": "~2.1.0", + "wd": "~0.2.2" }, "engines": { "node": ">=0.10.0" diff --git a/src/environment/__tests__/ReactWebWorker-test.js b/src/environment/__tests__/ReactWebWorker-test.js index 87f093f8c0d5e..8703dbb2a1cf1 100644 --- a/src/environment/__tests__/ReactWebWorker-test.js +++ b/src/environment/__tests__/ReactWebWorker-test.js @@ -22,11 +22,11 @@ "use strict"; describe('ReactWebWorker', function() { - it('can run React in a web worker', function() { + ;(typeof Worker == 'undefined' ? xit : it)('can run React in a web worker', function() { var done = false; var error; - var worker = new Worker('/worker.js'); + var worker = new Worker(window.ReactWebWorker_URL || '/src/test/worker.js?_=' + Date.now().toString(36)); worker.addEventListener('message', function(e) { var data = JSON.parse(e.data); if (data.type == 'error') { diff --git a/src/test/worker.js b/src/test/worker.js index 2918cb6e4deda..7ba7e1ffc734c 100644 --- a/src/test/worker.js +++ b/src/test/worker.js @@ -6,7 +6,7 @@ var global = {}; importScripts("phantomjs-shims.js"); try { - importScripts("react.js"); + importScripts("../../build/react.js"); } catch (e) { postMessage(JSON.stringify({ type: 'error', diff --git a/test/index.html b/test/index.html index 97fbfb0479764..de8c0aaf9a36f 100644 --- a/test/index.html +++ b/test/index.html @@ -1,23 +1,38 @@ - - -
- - - - - - - - + 'lib/testImageURL.browser.js', + 'lib/reportTestResults.browser.js', + + '../build/react.js', + '../build/react-test.js', + 'the-files-to-test.generated.js', + 'lib/jasmine-execute.js' + ]; + + if (typeof Function.prototype.bind == 'undefined') { + urls.unshift('../node_modules/es5-shim/es5-sham.js'); + urls.unshift('../node_modules/es5-shim/es5-shim.js'); + } + + var cacheBust = '?_=' + Date.now().toString(36); + + for (var urls_index = -1, urls_length = urls.length; ++urls_index < urls_length;) { + document.write(' diff --git a/test/lib/jasmine-execute.js b/test/lib/jasmine-execute.js new file mode 100644 index 0000000000000..b0460e2508fd9 --- /dev/null +++ b/test/lib/jasmine-execute.js @@ -0,0 +1,14 @@ +document.write(''); + +;(function(env){ + env.addReporter(new jasmine.HtmlReporter); + // Clean up any nodes the previous test might have added. + env.afterEach(function() { + harness.removeNextSiblings(document.body); + harness.removeNextSiblings(document.getElementById("HTMLReporter")); + }); + + window.onload = function(){ + env.execute(); + } +})(jasmine.getEnv()); diff --git a/test/lib/reportTestResults.browser.js b/test/lib/reportTestResults.browser.js new file mode 100644 index 0000000000000..de65053399d9e --- /dev/null +++ b/test/lib/reportTestResults.browser.js @@ -0,0 +1,76 @@ +console._error = console.error; +console._warn = console.warn; +console._log = console.log; + +console.log = window.print = function(message){ + console._log(message); + testImageURL('/print?type=log&message=' + encodeURIComponent(message) + '&_=' + Date.now().toString(36)); +}; + +console.error = function(message){ + console._error(message); + testImageURL('/print?type=error&message=' + encodeURIComponent(message) + '&_=' + Date.now().toString(36)); +}; + +console.warn = function(message){ + console._warn(message); + testImageURL('/print?type=warn&message=' + encodeURIComponent(message) + '&_=' + Date.now().toString(36)); +}; + +;(function(env){ + + env.addReporter(new jasmine.JSReporter()); + env.addReporter(new TAPReporter(window.print)); + + function report(){ + if (typeof jasmine.getJSReport != 'function') return setTimeout(report, 100); + postDataToURL(JSON.stringify(jasmine.getJSReport()), '/reportTestResults', function(error, event){ + if (error) return console.error(error); + }); + } + + var oldCallback = env.currentRunner().finishCallback; + env.currentRunner().finishCallback = function(){ + if (oldCallback) oldCallback.apply(this, arguments); + report(); + }; + + function postDataToURL(data, url, callback){ + var id = '$' + (+new Date()).toString(36); + + var postReportingTarget = document.createElement('iframe'); + postReportingTarget.id = postReportingTarget.name = 'postReportingTarget' + id; + + var postReportingForm = document.createElement('form'); + postReportingForm.method = 'POST'; + postReportingForm.action = url; + postReportingForm.target = postReportingTarget.name; + + var postReportingData = document.createElement('input'); + postReportingData.type = 'hidden'; + postReportingData.name = 'data'; + postReportingData.value = data || '{"error":"unknown error in postReportingData"}'; + + postReportingForm.appendChild(postReportingData); + postReportingForm.appendChild(postReportingTarget); + postReportingForm.style.cssText = "visibility:hidden; position:absolute; bottom:100%; right:100%"; + + function done(error, event){ + postReportingForm.parentNode.removeChild(postReportingForm); + callback(error, event); + } + + postReportingTarget.onerror = function(error){ + done(error); + } + postReportingTarget.onload = function(event){ + done(null, event); + } + document.body.appendChild(postReportingForm); + setTimeout(function(){ + postReportingForm.submit(); + },0); + } + +}(window.jasmine.getEnv())); + diff --git a/test/lib/testImageURL.browser.js b/test/lib/testImageURL.browser.js new file mode 100644 index 0000000000000..b02dd899a65bf --- /dev/null +++ b/test/lib/testImageURL.browser.js @@ -0,0 +1,62 @@ +testImageURL._recycle = function(img){ + console.log('_recycle', img); + try { + img.src = ''; + img.onload = img.onerror = null; + } catch(e){} + testImageURL._recycleBin.push(img); +} +testImageURL.getImage = function(callback){ + // if (!testImageURL._recycleBin) testImageURL._recycleBin = [new Image(),new Image(),new Image(),new Image()]; + // function get(){ + // if (testImageURL._recycleBin.length === 0) return setTimeout(get, 100); + // callback(testImageURL._recycleBin.shift(), testImageURL._recycle); + // } + // get(); + callback(new Image(), function recycle(){}); +} + +testImageURL.defaultCallback = function(error, event){} + +function testImageURL(url, timeout, callback){ + if (typeof timeout == 'function'){ + callback = timeout; + timeout = testImageURL.timeout; + } + if (typeof callback != 'function') callback = testImageURL.defaultCallback; + + testImageURL.getImage(function(img, done){ + function callbackWrapper(error, event){ + callbackWrapper = testImageURL.noop; + testImageURL.running = (testImageURL.running || 0) - 1; + clearTimeout(timer); + done(img); + img = url = timeout = null; + callback(error, event); + error = event = callback = null; + } + + var timer = setTimeout(function(){callbackWrapper(Error('timeout'));}, timeout); + + try { + img.onload = function(event){ callbackWrapper(null, event || window.event); }; + img.onerror = function(error){ callbackWrapper(error); }; + img.src = url; + testImageURL.running = (testImageURL.running || 0) + 1; + + if (img.complete === true + || img.readyState == 4 + || img.width > 0 + || img.height > 0 + || img.readyState == 'complete' + ) callbackWrapper(null, null); + } + catch(error){ + callbackWrapper(error); + } + }); +} + +testImageURL.noop = function(){}; + +testImageURL.timeout = 5000; diff --git a/test/phantom-harness.js b/test/phantom-harness.js deleted file mode 100644 index c89f971a4425c..0000000000000 --- a/test/phantom-harness.js +++ /dev/null @@ -1,137 +0,0 @@ -var slice = Array.prototype.slice; -var argv = slice.call(require("system").args); - -// Hard to believe PhantomJS has no equivalent of Node's "path" module. -var fs = require("fs"); -var splat = [fs.workingDirectory, argv[0]] - .join(fs.separator) - .split(fs.separator); - -var harness = splat.pop(); -if (harness !== "phantom-harness.js") { - console.error("wrong harness: " + harness); - phantom.exit(-1); -} - -var cwd = splat.join(fs.separator); -fs.changeWorkingDirectory(cwd); - -// Hard to believe PhantomJS has no option parsing module. -var port = 8080; -var debug = false; -var tests = []; -var rest = []; -while (argv.length > 0) { - var arg = argv.pop(); - if (arg === "--port") { - port = +rest.pop(); - } else if (arg === "--debug") { - debug = true; - } else if (arg === "--tests") { - while (rest.length > 0) - tests.push(rest.pop()); - } - rest.push(arg); -} - -// Dynamically enable the individual tests. -var indexHtml = fs.read("index.html").replace( - /^(\s*)ENABLE_TESTS_HERE/m, - function(placeholder, leadingSpace) { - return leadingSpace + tests.map(function(testID) { - return "harness.enableTest(" + JSON.stringify(testID) + ");"; - }).join("\n" + leadingSpace); - } -); - -var server = require("webserver").create(); -server.listen(port, function(req, res) { - var file = req.url.replace(/^\/+/, ""); - var content; - - switch (file) { - case "jasmine.js": - case "react.js": - case "react-test.js": - file = "../build/" + file; - break; - - case "phantomjs-shims.js": - case "worker.js": - file = "../src/test/" + file; - break; - - case "jasmine.css": - file = "../vendor/jasmine/" + file; - break; - - case "": - default: - file = "index.html"; - content = indexHtml; // Prevents calling fs.read again. - break; - } - - if (/\.css$/i.test(file)) { - res.setHeader("Content-Type", "text/css"); - } else if (/\.js/i.test(file)) { - res.setHeader("Content-Type", "text/javascript"); - } else { - res.setHeader("Content-Type", "text/html"); - } - - res.statusCode = 200; - res.write(content || fs.read(file)); - res.close(); -}); - -var url = "http://localhost:" + port; -var green = "\033[32m"; -var cyan = "\033[36m"; -var reset = "\033[0m"; - -if (debug) { - console.log(green); - console.log("PhantomJS received the " + cyan + "--debug" + green + " option."); - console.log("Load " + cyan + url + green + " in your browser to execute " + - "the test suite."); - console.log("Type " + cyan + "control-C" + green + " to terminate the " + - "PhantomJS process."); - console.log(reset); - - // Leave PhantomJS running until killed with control-C... - -} else { - var page = require("webpage").create(); - var timeoutSecs = 60; - - page.onCallback = function(data) { - switch (data.type) { - case "console": - console[data.method].apply(console, data.args); - break; - - case "exit": - // PhantomJS crashes sometimes unless we call phantom.exit in its own - // event loop tick. - setTimeout(function() { - phantom.exit(data.code); - }, 10); - break; - } - }; - - page.open(url, function(status) { - if (status !== "success") { - console.error("failed to open " + url); - phantom.exit(-1); - } - - setTimeout(function() { - console.error( - "PhantomJS tests timed out after " + - timeoutSecs + " seconds."); - phantom.exit(-1); - }, timeoutSecs * 1e3); - }); -} diff --git a/vendor/jasmine-jsreporter/jasmine-jsreporter.js b/vendor/jasmine-jsreporter/jasmine-jsreporter.js new file mode 100755 index 0000000000000..67eeea3fca97d --- /dev/null +++ b/vendor/jasmine-jsreporter/jasmine-jsreporter.js @@ -0,0 +1,161 @@ +/* + This file is part of the Jasmine JSReporter project from Ivan De Marino. + + Copyright (C) 2011 Ivan De Marino (aka detro, aka detronizator), http://blog.ivandemarino.me, ivan.de.marino@gmail.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the