]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
run qunit tests in phantomjs for travis-ci
authorJacob Thornton <jacobthornton@gmail.com>
Fri, 20 Apr 2012 00:34:07 +0000 (17:34 -0700)
committerJacob Thornton <jacobthornton@gmail.com>
Fri, 20 Apr 2012 00:34:07 +0000 (17:34 -0700)
Makefile
README.md
js/tests/index.html
js/tests/phantom.js [new file with mode: 0644]
js/tests/server.js [new file with mode: 0644]
js/tests/unit/bootstrap-phantom.js [new file with mode: 0644]
package.json

index e7a0f035f01fed6713e50ba6c319a4de5ba6644f..9a4ffa4536dc591cdf10833059cf991edfc82359 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,7 @@ BOOTSTRAP_RESPONSIVE_LESS = ./less/responsive.less
 DATE=$(shell date +%I:%M%p)
 CHECK=\033[32m✔\033[39m
 
+
 #
 # BUILD DOCS
 #
@@ -37,13 +38,16 @@ build:
        @echo "<3 @mdo and @fat\n"
 
 #
-# RUN JSHINT
-# TODO: run unittests
+# RUN JSHINT & QUNIT TESTS IN PHANTOMJS
 #
 
 test:
        jshint js/*.js --config js/.jshintrc
        jshint js/tests/unit/*.js --config js/.jshintrc
+       node js/tests/server.js &
+       phantomjs js/tests/phantom.js "http://localhost:3000/js/tests"
+       kill -9 `cat js/tests/pid.txt`
+       rm js/tests/pid.txt
 
 #
 # BUILD SIMPLE BOOTSTRAP DIRECTORY
index f1a66eac3963b9189c60128184c170da1cc96bbc..54ea40577f64bfeb5a9f31639127111ad2a1b601 100644 (file)
--- a/README.md
+++ b/README.md
@@ -91,6 +91,9 @@ $ npm install recess uglify-js jshint -g
 + **build** - `make`
 Runs the recess compiler to rebuild the `/less` files and compiles the docs pages. Requires recess and uglify-js. <a href="http://twitter.github.com/bootstrap/less.html#compiling">Read more in our docs &raquo;</a>
 
++ **test** - `make test`
+Runs jshint and qunit tests headlessly in phantom js (used for ci). Depends on having phatomjs installed.
+
 + **watch** - `make watch`
 This is a convenience method for watching just Less files and automatically building them whenever you save. Requires the Watchr gem.
 
index 3e6cb9777c643ab9817b6f7bea26aca811d51667..2f8f71b12e143dc2e7760e026e8807cf0b424fc4 100644 (file)
@@ -11,6 +11,9 @@
   <link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen" />
   <script src="vendor/qunit.js"></script>
 
+  <!-- phantomjs logging script-->
+  <script src="unit/bootstrap-phantom.js"></script>
+
   <!--  plugin sources -->
   <script src="../../js/bootstrap-transition.js"></script>
   <script src="../../js/bootstrap-alert.js"></script>
diff --git a/js/tests/phantom.js b/js/tests/phantom.js
new file mode 100644 (file)
index 0000000..f172e7c
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Simple phantom.js integration script
+ * Adapted from Modernizr
+ */
+
+function waitFor(testFx, onReady, timeOutMillis) {
+    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timout is 3s
+        start = new Date().getTime(),
+        condition = false,
+        interval = setInterval(function() {
+            if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
+                // If not time-out yet and condition not yet fulfilled
+                condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
+            } else {
+                if(!condition) {
+                    // If condition still not fulfilled (timeout but condition is 'false')
+                    console.log("'waitFor()' timeout");
+                    phantom.exit(1);
+                } else {
+                    // Condition fulfilled (timeout and/or condition is 'true')
+                    typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
+                    clearInterval(interval); //< Stop this interval
+                }
+            }
+        }, 100); //< repeat check every 250ms
+};
+
+
+if (phantom.args.length === 0 || phantom.args.length > 2) {
+    console.log('Usage: phantom.js URL');
+    phantom.exit();
+}
+
+var page = new WebPage();
+
+// Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
+page.onConsoleMessage = function(msg) {
+    console.log(msg);
+};
+
+page.open(phantom.args[0], function(status){
+    if (status !== "success") {
+        console.log("Unable to access network");
+        phantom.exit();
+    } else {
+        waitFor(function(){
+            return page.evaluate(function(){
+                var el = document.getElementById('qunit-testresult');
+                if (el && el.innerText.match('completed')) {
+                    return true;
+                }
+                return false;
+            });
+        }, function(){
+            var failedNum = page.evaluate(function(){
+                var el = document.getElementById('qunit-testresult');
+                try {
+                    return el.getElementsByClassName('failed')[0].innerHTML;
+                } catch (e) { }
+                return 10000;
+            });
+            phantom.exit((parseInt(failedNum, 10) > 0) ? 1 : 0);
+        });
+    }
+});
\ No newline at end of file
diff --git a/js/tests/server.js b/js/tests/server.js
new file mode 100644 (file)
index 0000000..27d1bf2
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Simple connect server for phantom.js
+ * Adapted from Modernizr
+ */
+
+var connect = require('connect')
+  , args = process.argv.slice(2)
+  , fs = require('fs')
+  , folder = '/../../'
+  , port = '3000'
+
+var server = connect.createServer(
+    connect.static(__dirname + folder)
+).listen(port)
+
+fs.writeFileSync(__dirname + '/pid.txt', process.pid, 'utf-8')
+
+console.log("Server started on port %s in %s", port, folder)
\ No newline at end of file
diff --git a/js/tests/unit/bootstrap-phantom.js b/js/tests/unit/bootstrap-phantom.js
new file mode 100644 (file)
index 0000000..8bed5f6
--- /dev/null
@@ -0,0 +1,21 @@
+// Logging setup for phantom integration
+// adapted from Modernizr
+
+QUnit.begin = function() {
+       console.log("Starting test suite");
+       console.log("================================================\n");
+};
+
+QUnit.moduleDone = function(opts) {
+       if(opts.failed === 0) {
+               console.log("\u2714 All tests passed in '"+opts.name+"' module");
+       } else {
+               console.log("\u2716 "+ opts.failed +" tests failed in '"+opts.name+"' module");
+       }
+};
+
+QUnit.done = function(opts) {
+       console.log("\n================================================");
+       console.log("Tests completed in "+opts.runtime+" milliseconds");
+       console.log(opts.passed + " tests of "+opts.total+" passed, "+opts.failed+" failed.");
+};
\ No newline at end of file
index c32979e53d36171fdeb7ee1274668ea4b714bca8..5f54d5c78a4fd6c72bdedfe343532b86650bd5b2 100644 (file)
@@ -20,5 +20,6 @@
       "uglify-js": "*"
     , "jshint": "*"
     , "recess": "*"
+    , "connect": "*"
   }
 }
\ No newline at end of file