short answer: you need to run:
phantomjs.exe script-runner.js simple_test.html
Long answer:
You will need a javascript file that will call your tests, I wrote many variations of this, but the best one I found is with QUnitTeamCityDriver https://github.com/redbadger/QUnitTeamCityDriver . I used with minor changes, although I do not work with TeamCity.
Below is the contents of the file with some changes (I used it in one of my recent projects), but you should find the original on github (name it script -runner.js and enter the same folder as phantom.exe for convenience):
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 supposed to do once the condition is fulfilled clearInterval(interval); //< Stop this interval } } }, 100); //< repeat check every 250ms }; var page = new WebPage(); // Route "console.log()" calls from within the Page context to the main Phantom context (ie 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 () { phantom.exit(); }, 10000); } });
This will open your html page and parse it. That was one of the confusing things for me, phantomjs is the browser at the end, you have to pass this script to it, which will eventually open the HTML page, not the Javascript file. Therefore you call phantomjs as follows:
phantomjs.exe script-runner.js [path to file containing tests]
so in your case it will be:
phantomjs.exe script-runner.js simple_test.html
The last bit of the puzzle is that on your html page containing the test, you must add a link to the javascript file, this is a file called QUnitTeamCityDriver.js in your links. This is what will connect to qUnit events and send them to phantom to decide if the test passed and which failed. The contents of the file (again, you can probably find the best updated version on the project page on github):
if (navigator.userAgent.indexOf("PhantomJS") !== -1) { String.prototype.format = function () { var args = arguments; return this.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : '{' + number + '}'; }); }; var suiteName = "QUnit Tests"; var currentTestName = ""; var hasBegun = false; qunitBegin = function () { console.log("[testSuiteStarted name='{0}']".format(suiteName)); }; QUnit.testStart = function (args) { if (!hasBegun) { qunitBegin(); hasBegun = true; } currentTestName = args.name; }; QUnit.moduleStart = function (args) { console.log("Module started: {0}".format(args.name)); }; QUnit.log = function (args) { var currentAssertion = "{0} > {1}".format(currentTestName, args.message);
This basically intercepts the callbacks defined by QUnit and sends a message to the console, which are shown by phantomjs. The QUnit callback documentation is here: http://api.qunitjs.com/category/callbacks/
As for connecting to TeamCity, perhaps itβs just a parameter to determine the build step for checking a specific line in the output (for example, the presence of β[testFailed]β in the output indicates a failure), I did this with CruiseControl and also created a Nunit wrapper around it. At the end, the same concept is used, you simply parse the output of phatomjs to check for the presence of [testFailed] or any line that indicates a failure.