From 6a1ab4e39fa269e0a4b07380bb2d94a843926865 Mon Sep 17 00:00:00 2001 From: Jim Witschey Date: Fri, 25 Jul 2014 11:23:47 -0400 Subject: [PATCH] adds saucelabs integration to unit tests --- .npmignore | 0 Gruntfile.js | 75 +++++++++++++++++++++++++++++++++++++++++- package.json | 18 +++++++++- tests/e2e/tests.js | 28 ++++++++++++++++ tests/mithril-tests.js | 14 ++++++-- tests/test.js | 29 +++++++++++++++- 6 files changed, 158 insertions(+), 6 deletions(-) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..e69de29b diff --git a/Gruntfile.js b/Gruntfile.js index c79039aa..812393da 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,4 +1,5 @@ module.exports = function(grunt) { + _ = require('lodash'); var version = "0.1.19" @@ -58,6 +59,62 @@ module.exports = function(grunt) { makeTasks("guide", guide) makeTasks("api", api) + var sauceBrowsers =[ + { browserName: 'firefox', version: '19', platform: 'XP' }, + { browserName: "internet explorer", platform: "XP", version: "6"}, + { browserName: "safari", platform: "OS X 10.9", version: "7"}, + { browserName: "iPad", platform: "OS X 10.9", version: "7.1"}, + { browserName: "opera", platform: "Linux", version: "12"}, + { browserName: "chrome", platform: "XP", version: "26"}, + { browserName: "chrome", platform: "Windows 8", version: "26"}, + ]; + + var sauceOnTestComplete = function(result, callback) { + var request = require('request'); + + var user = process.env.SAUCE_USERNAME; + var pass = process.env.SAUCE_ACCESS_KEY; + + request.put({ + url: ['https://saucelabs.com/rest/v1', user, 'jobs', result.job_id].join('/'), + auth: { user: user, pass: pass }, + json: { passed: result.passed } + }, function (error, response, body) { + if (error) { + callback(error); + } else if (response.statusCode !== 200) { + callback(new Error('Unexpected response status: ' + + response.statusCode + "\n ")); + } else { + callback(null, result.passed); + } + }); + }; + + var sauceBaseOptions = { + username: process.env.SAUCE_USERNAME, + key: process.env.SAUCE_ACCESS_KEY, + testname: "Mithril Tests " + new Date().toJSON(), + browsers: sauceBrowsers, + sauceConfig: { + "record-video": false, + "record-screenshots": false, + }, + build: process.env.TRAVIS_JOB_ID, + onTestComplete: sauceOnTestComplete, + tunnelTimeout: 5, + }; + var sauceCustomOptions = { + testname: "Mithril Custom Tests "+ new Date().toJSON(), + urls: ["http://127.0.0.1:8000/tests/index.html"], + }; + _.assign(sauceCustomOptions, sauceBaseOptions); + var sauceQunitOptions = { + testname: "qUnit Tests "+ new Date().toJSON(), + urls: ["http://127.0.0.1:8000/tests/e2e/test.html"], + }; + _.assign(sauceQunitOptions, sauceBaseOptions); + var currentVersionArchiveFolder = archiveFolder + "/v" + version grunt.initConfig({ md2html: md2htmlTasks, @@ -104,7 +161,19 @@ module.exports = function(grunt) { }, qunit: { all: ['tests/e2e/**/*.html'] - }, + }, + "saucelabs-custom": { + all:{ + options: sauceCustomOptions + } + }, + "saucelabs-qunit": { + all:{ + options: sauceQunitOptions + } + }, + watch: {}, + connect: { server: { options: { @@ -129,10 +198,14 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-zip'); grunt.loadNpmTasks('grunt-contrib-qunit'); grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-saucelabs'); grunt.registerTask("build", ["test", "uglify", "zip", "md2html", "replace", "copy", "clean"]); grunt.registerTask("test", ["concat", "execute"]); grunt.registerTask('teste2e', ['connect', 'qunit']); grunt.registerTask("default", ["build"]); + grunt.registerTask("sauce-qunit", ["connect", "saucelabs-qunit"]); + grunt.registerTask("sauce-custom", ["connect", "saucelabs-custom"]); + grunt.registerTask("sauce-all", ["connect", "saucelabs-qunit", "saucelabs-custom"]); }; diff --git a/package.json b/package.json index fd91cb67..b188a2fc 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,22 @@ "grunt-replace": "*", "grunt-contrib-qunit": "*", "grunt-contrib-connect": "*", - "grunt-zip": "*" + "grunt-zip": "*", + + "grunt-contrib-connect": "~0.7.1", + "grunt-contrib-jshint": "~0.10.0", + "grunt-contrib-watch": "~0.6.1", + "grunt-jscs-checker": "^0.4.4", + "grunt-sauce-tunnel": "^0.2.1", + "load-grunt-config": "^0.9.2", + "merge": "^1.1.3", + "publish": "~0.3.2", + "grunt-saucelabs": "*", + "request": "~2.35.0", + "q": "~1.0.0", + "saucelabs": "~0.1.1", + "sauce-tunnel": "~2.0.6", + "colors": "~0.6.2", + "lodash": "~2.4.1" } } diff --git a/tests/e2e/tests.js b/tests/e2e/tests.js index 1a1e4241..d80c1e33 100644 --- a/tests/e2e/tests.js +++ b/tests/e2e/tests.js @@ -1,3 +1,31 @@ +//saucelabs reporting; see https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit +var log = []; +var testName; +QUnit.done(function (test_results) { + var tests = []; + for(var i = 0, len = log.length; i < len; i++) { + var details = log[i]; + tests.push({ + name: details.name, + result: details.result, + expected: details.expected, + actual: details.actual, + source: details.source + }); + } + test_results.tests = tests; + + window.global_test_results = test_results; +}); +QUnit.testStart(function(testDetails){ + QUnit.log(function(details){ + if (!details.result) { + details.name = testDetails.name; + log.push(details); + } + }); +}); + //qunit doesn't support Function.prototype.bind... if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index 1a61a1b6..c92e55ed 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -1575,7 +1575,15 @@ function testMithril(mock) { } -//mocks -testMithril(mock.window) +//test reporting for saucelabs +window.global_test_results = { + tests: [], + duration: 0, + passed: 0, + failed: 0 +}; -test.print(console.log) +//mock +testMithril(mock.window); + +test.print(function(value){console.log(value)}); \ No newline at end of file diff --git a/tests/test.js b/tests/test.js index 16e45a21..a24f2412 100644 --- a/tests/test.js +++ b/tests/test.js @@ -1,7 +1,34 @@ function test(condition) { + var duration = 0; + var start = 0; + var result = true; + if (performance.now) { + start = performance.now(); + } try {if (!condition()) throw new Error} - catch (e) {console.error(e);test.failures.push(condition)} + catch (e) {result = false;console.error(e);test.failures.push(condition)} + if (performance.now) { + duration = performance.now() - start; + } + test.total++ + + test_obj = { + name: "" + test.total, + result: result, + duration: duration + } + if (!result) { + message: "failed: " + condition, + window.global_test_results.tests.push(test_obj) + } + + window.global_test_results.duration += duration; + if (result) { + window.global_test_results.passed++; + } else { + window.global_test_results.failed++; + } } test.total = 0 test.failures = []