#!/usr/bin/env phantomjs /* * Copyright (C) 2013 Red Hat, Inc. * * Cockpit is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * Cockpit is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Cockpit; If not, see . */ /* * This is a phantom driver for QUnit which outputs TAP */ var sys = require('system'); var fs = require('fs'); var child = require("child_process"); var url = null; var server = []; var proc; /* * Strip prefix from url * We need this to compensate for automake test generation behavior: * The tests are called with the path (relative to the build directory) of the testfile, * but from the build directory. Some tests make assumptions regarding the structure of the * filename. In order to make sure that they receive the same name, regardless of actual * build directory location, we need to strip that prefix (path from build to source directory) * from the filename */ var strip = ""; var failed = false; var args = sys.args.slice(1); var arg, optmode = true; while (args.length > 0) { arg = args.shift(); if (optmode) { if (arg === "--") { optmode = false; continue; } else if (arg.indexOf("-") !== 0) { optmode = false; } else if (arg.indexOf("--strip=") === 0) { strip = arg.substring(9); } else if (arg === "--strip") { strip = args.shift(); } else { sys.stderr.write("tap-phantom: invalid option: " + arg + "\n"); failed = true; usage(); } } if (!optmode) { if (args.length > 0) { server.push(arg); } else { url = arg; if (url.indexOf(strip) == 0) url = url.slice(strip.length); } } } if (!failed) { if (server.length > 0) launch(); else run(url); } function usage(code) { sys.stderr.write('usage: tap-phantom [--strip=../] -- [server ...] file\n'); phantom.exit(code === undefined ? 2 : code); } function calc_srcdir() { var dir = sys.args[0]; var pos = dir.lastIndexOf(fs.separator); if(pos == -1) return "."; else return dir.substring(0, pos); } function print_error(msg, trace, out, prefix) { out.writeLine(prefix + msg); if (trace && trace.length) { trace.forEach(function(frame) { out.writeLine(prefix + " " + (frame.file || frame.sourceURL) + ':' + frame.line + (frame.function ? ' (in function ' + frame.function +')' : '')); }); } } function run(url) { var page = require('webpage').create(); page.viewportSize = { width: 800, height: 480 }; page.onConsoleMessage = function(msg, lineNum, sourceId) { /* All done with testing */ if (msg === "phantom-tap-done") { if (proc) { proc.kill("TERM"); } else { setTimeout(function() { phantom.exit(0); }, 0); } } else if (msg == "phantom-tap-error") setTimeout(function() { phantom.exit(1); }, 0); else if (msg == "phantom-tap-expect-resource-error") page.onResourceError = null; /* TAP lines go to stdout */ else if (msg.match(/^ok [0-9]+/i) || msg.match(/^not ok [0-9]+/i) || msg.match(/^Bail out!/i) || msg.match(/^[0-9]+\.\.[0-9]+/) || msg.match(/^# /)) sys.stdout.writeLine(msg); /* Everything else goes to stderr */ else sys.stderr.writeLine(msg); }; page.onResourceError = function(ex) { console.error('Unable to load resource: ' + ex.url + ': ' + ex.errorString); phantom.exit(1); }; phantom.onError = function(msg, trace) { print_error(msg, trace, sys.stderr, ""); phantom.exit(1); }; page.onError = function(msg, trace) { print_error(msg, trace, sys.stdout, "# "); phantom.exit(1); }; page.open(url, function(status) { if (status !== "success") { console.log("Unable to load:", url); phantom.exit(1); } page.evaluate(function() { if (typeof tests_included === "undefined") { console.log("Tests not properly included"); phantom.exit(1); } }); }); } function launch() { var running = false; var buffer = ""; proc = child.spawn(server[0], server.slice(1)); if (proc.pid === 0) { console.log("tap-phantom: couldn't spawn: " + server[0]); phantom.exit(127); return; } proc.stdout.on("data", function(data) { if (running) return; buffer = buffer + data; var pos = buffer.indexOf('\n'); if (pos >= 0) { running = true; run(buffer.substring(0, pos) + "/" + url); } }); proc.stderr.on("data", function(data) { sys.stderr.write(data); }); proc.on("exit", function(code) { if (code != 0) sys.stderr.writeLine(server[0] + " exited unsuccessfully: " + code); phantom.exit(code); }); }