Skip to content

Instantly share code, notes, and snippets.

@gmarik
Created October 21, 2011 21:44

Revisions

  1. gmarik revised this gist Oct 21, 2011. 1 changed file with 8 additions and 0 deletions.
    8 changes: 8 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -7,6 +7,14 @@
    Tests completed in 21 milliseconds.
    5 tests of 5 passed, 0 failed.

    # Installation

    - `brew install phantomjs`
    - `git clone git://gist.github.com/1305062.git phantomjs-qunit && cd phantomjs-qunit`

    # Run

    - `$ phantomjs run-qunit.js file://`pwd`/test.html`

    [qunit]:https://github.com/jquery/qunit
    [phantomjs]:http://www.phantomjs.org/
  2. gmarik created this gist Oct 21, 2011.
    13 changes: 13 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    # About

    minimal example of using [phantomjs] with [qunit]

    $ phantomjs run-qunit.js file://`pwd`/test.html
    'waitFor()' finished in 200ms.
    Tests completed in 21 milliseconds.
    5 tests of 5 passed, 0 failed.


    [qunit]:https://github.com/jquery/qunit
    [phantomjs]:http://www.phantomjs.org/
    [run-qunit.js]:https://raw.github.com/ariya/phantomjs/master/examples/run-qunit.js
    74 changes: 74 additions & 0 deletions run-qunit.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,74 @@
    /**
    * Wait until the test condition is true or a timeout occurs. Useful for waiting
    * on a server response or for a ui change (fadeIn, etc.) to occur.
    *
    * @param testFx javascript condition that evaluates to a boolean,
    * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
    * as a callback function.
    * @param onReady what to do when testFx condition is fulfilled,
    * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
    * as a callback function.
    * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
    */
    function waitFor(testFx, onReady, timeOutMillis) {
    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 30001, //< 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')
    console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
    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: run-qunit.js URL');
    phantom.exit(1);
    }

    var page = require('webpage').create();

    // 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(1);
    } 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');
    console.log(el.innerText);
    try {
    return el.getElementsByClassName('failed')[0].innerHTML;
    } catch (e) { }
    return 10000;
    });
    phantom.exit((parseInt(failedNum, 10) > 0) ? 1 : 0);
    });
    }
    });
    34 changes: 34 additions & 0 deletions test.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    <!DOCTYPE html>
    <html>
    <head>
    <title>QUnit Test Suite</title>
    <link rel="stylesheet" href="https://raw.github.com/jquery/qunit/master/qunit/qunit.css" type="text/css" media="screen">
    <script type="text/javascript" src="https://raw.github.com/jquery/qunit/master/qunit/qunit.js"></script>
    <!-- Your project file goes here -->
    <!-- <script type="text/javascript" src="myProject.js"></script> -->
    <!-- Your tests file goes here -->
    <!-- <script type="text/javascript" src="myTests.js"></script> -->
    </head>
    <body>
    <h1 id="qunit-header">QUnit Test Suite</h1>
    <h2 id="qunit-banner"></h2>
    <div id="qunit-testrunner-toolbar"></div>
    <h2 id="qunit-userAgent"></h2>
    <ol id="qunit-tests"></ol>

    <script>
    // Let's test this function
    function isEven(val) {
    return val % 2 === 0;
    }

    test('isEven()', function() {
    ok(isEven(0), 'Zero is an even number');
    ok(isEven(2), 'So is two');
    ok(isEven(-4), 'So is negative four');
    ok(!isEven(1), 'One is not an even number');
    ok(!isEven(-7), 'Neither is negative seven');
    })
    </script>
    </body>
    </html>