Second commit
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
bower_components
|
||||
results/*
|
||||
@@ -0,0 +1,3 @@
|
||||
angular.module('Spaghetti', [
|
||||
'Results'
|
||||
]);
|
||||
@@ -0,0 +1,48 @@
|
||||
var app = angular.module('Results', []);
|
||||
|
||||
app.controller('ResultsCtrl', function ($scope) {
|
||||
// Grab results from nodeJS served page
|
||||
$scope.phantomasResults = window._phantomas_results;
|
||||
|
||||
$scope.slowRequestsOn = false;
|
||||
$scope.slowRequestsLimit = 5;
|
||||
|
||||
$scope.onNodeDetailsClick = function(node) {
|
||||
var isOpen = node.data.showDetails;
|
||||
if (!isOpen) {
|
||||
// Close all other nodes
|
||||
$scope.phantomasResults.javascript.children.forEach(function(currentNode) {
|
||||
currentNode.data.showDetails = false;
|
||||
});
|
||||
|
||||
// Parse the backtrace
|
||||
if (!node.data.parsedBacktrace) {
|
||||
node.data.parsedBacktrace = parseBacktrace(node.data.backtrace);
|
||||
}
|
||||
|
||||
}
|
||||
node.data.showDetails = !isOpen;
|
||||
};
|
||||
|
||||
function parseBacktrace(str) {
|
||||
var splited = str.split(' / ');
|
||||
var out = [];
|
||||
splited.forEach(function(trace) {
|
||||
var result = /^(\S*)\s?\(?(https?:\/\/\S+):(\d+)\)?$/g.exec(trace);
|
||||
if (result && result[2].length > 0) {
|
||||
var filePath = result[2];
|
||||
var chunks = filePath.split('/');
|
||||
var fileName = chunks[chunks.length - 1];
|
||||
|
||||
out.push({
|
||||
fnName: result[1],
|
||||
fileName: fileName,
|
||||
filePath: filePath,
|
||||
line: result[3]
|
||||
});
|
||||
}
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
.url {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.launchBtn {
|
||||
background: #e74c3c;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
input[type=submit], input.url {
|
||||
padding: 0 0.5em;
|
||||
margin: 0.5em;
|
||||
font-size: 1.2em;
|
||||
height: 2em;
|
||||
border: 0 solid;
|
||||
border-radius: 0.5em;
|
||||
box-shadow: 0.1em 0.2em 0 0 #5e2846;
|
||||
outline: none;
|
||||
}
|
||||
input[type=submit]:hover {
|
||||
color: #ddd;
|
||||
}
|
||||
input[type=submit].clicked {
|
||||
color: #ddd;
|
||||
position: relative;
|
||||
left: 0.1em;
|
||||
top: 0.2em;
|
||||
box-shadow: none;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#status {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
html {
|
||||
margin: 100px 50px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 1280px;
|
||||
background: #9c4274;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
body, input[type=submit], input[type=text], input[type=number], button {
|
||||
font-family: 'Century Gothic', helvetica, arial, sans-serif;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
.testedUrl {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.execution {
|
||||
margin-top: 3em;
|
||||
padding: 1em;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
border-radius: 0.5em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.filters {
|
||||
margin: 1em 0;
|
||||
padding: 0.5em;
|
||||
border: 1px dotted #aaa;
|
||||
}
|
||||
|
||||
.slowRequestsLimit {
|
||||
width: 3em;
|
||||
font-size: 1em;
|
||||
text-align: right;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
input.textFilter {
|
||||
box-shadow: none;
|
||||
font-size: 1em;
|
||||
padding: 0 0.2em;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: none;
|
||||
width: 15em;
|
||||
}
|
||||
|
||||
.table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
border-spacing: 0.25em;
|
||||
}
|
||||
|
||||
.table > div {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.table > .headers > div {
|
||||
font-weight: bold;
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
|
||||
.table > div > div {
|
||||
padding: 0.1em 1em;
|
||||
background: #f2f2f2;
|
||||
display: table-cell;
|
||||
text-align: left;
|
||||
}
|
||||
.table > div.jsError > .type, .table > div.jsError > .value {
|
||||
color: #e74c3c;
|
||||
font-weight: bold;
|
||||
}
|
||||
.table > div.showingDetails > div {
|
||||
background: #f1c40f;
|
||||
}
|
||||
|
||||
.table > div > .index {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.table > div > .type {
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
.table > div > .value {
|
||||
width: 70%;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.table > div > .details {
|
||||
position: relative;
|
||||
}
|
||||
.table > div > .details button {
|
||||
color: #f1c40f;
|
||||
font-weight: bold;
|
||||
border: 2px solid #f1c40f;
|
||||
border-radius: 50%;
|
||||
background: transparent;
|
||||
height: 2em;
|
||||
width: 2em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.detailsOverlay {
|
||||
position: absolute;
|
||||
right: 3em;
|
||||
top: -3em;
|
||||
width: 45em;
|
||||
padding: 0 1em 1em;
|
||||
background: #fff;
|
||||
border: 2px solid #f1c40f;
|
||||
border-radius: 0.5em;
|
||||
z-index: 1;
|
||||
}
|
||||
@media screen and (max-width: 1024px) {
|
||||
.detailsOverlay {
|
||||
width: 25em;
|
||||
}
|
||||
}
|
||||
.detailsOverlay .closeBtn {
|
||||
position: absolute;
|
||||
top: 0.5em;
|
||||
right: 0.5em;
|
||||
color: #f1c40f;
|
||||
cursor: pointer;
|
||||
}
|
||||
.detailsOverlay .trace {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.table > div > .duration {
|
||||
text-align: center;
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
.warningIcon {
|
||||
display: inline-block;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
background: url('data:image/svg+xml;utf8,<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" xmlns:xlink="http://www.w3.org/1999/xlink"><title/><defs/><g fill="none" fill-rule="evenodd" id="Icons new Arranged Names Color" stroke="none" stroke-width="1"><g fill="#e74c3c" id="101 Warning"><path d="M14.4242327,6.14839275 C15.2942987,4.74072976 16.707028,4.74408442 17.5750205,6.14839275 L28.3601099,23.59738 C29.5216388,25.4765951 28.6755462,27 26.4714068,27 L5.5278464,27 C3.32321557,27 2.47386317,25.4826642 3.63914331,23.59738 Z M16,20 C16.5522847,20 17,19.5469637 17,19.0029699 L17,12.9970301 C17,12.4463856 16.5561352,12 16,12 C15.4477153,12 15,12.4530363 15,12.9970301 L15,19.0029699 C15,19.5536144 15.4438648,20 16,20 Z M16,24 C16.5522848,24 17,23.5522848 17,23 C17,22.4477152 16.5522848,22 16,22 C15.4477152,22 15,22.4477152 15,23 C15,23.5522848 15.4477152,24 16,24 Z M16,24" id="Triangle 29"/></g></g></svg>') no-repeat 0 3px;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Javascript Spaghetti Profiler</title>
|
||||
<link rel="stylesheet" type="text/css" href="/public/styles/main.css">
|
||||
<link rel="stylesheet" type="text/css" href="/public/styles/index.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Javascript Spaghetti Profiler</h1>
|
||||
|
||||
<form method="post" action="/launchTest">
|
||||
<input type="text" name="url" placeholder="http://www.mysite.com" class="url" />
|
||||
<input type="submit" value="Launch test" class="launchBtn" onclick="this.className += ' clicked'" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,47 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Javascript Spaghetti Profiler</title>
|
||||
<link rel="stylesheet" type="text/css" href="/public/styles/main.css">
|
||||
<link rel="stylesheet" type="text/css" href="/public/styles/launchTest.css">
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Javascript Spaghetti Profiler</h1>
|
||||
|
||||
<div id="status"></div>
|
||||
|
||||
<div>%%TEST_URL%%</div>
|
||||
|
||||
<script>
|
||||
var testId = '%%TEST_ID%%';
|
||||
var statusElement = document.getElementById('status');
|
||||
var socket = io();
|
||||
|
||||
function askStatus() {
|
||||
socket.emit('waiting', testId);
|
||||
}
|
||||
|
||||
socket.on('running', function() {
|
||||
statusElement.innerHTML = 'Running';
|
||||
setTimeout(askStatus, 200);
|
||||
});
|
||||
|
||||
socket.on('position', function(position) {
|
||||
statusElement.innerHTML = 'Waiting behind ' + position + ' other tests';
|
||||
setTimeout(askStatus, 2000);
|
||||
});
|
||||
|
||||
socket.on('complete', function() {
|
||||
statusElement.innerHTML = 'Test complete';
|
||||
window.location.replace('/results/' + testId);
|
||||
});
|
||||
|
||||
socket.on('404', function() {
|
||||
statusElement.innerHTML = 'Test not found';
|
||||
});
|
||||
|
||||
askStatus();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,113 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Javascript Spaghetti Profiler</title>
|
||||
<link rel="stylesheet" type="text/css" href="/public/styles/main.css">
|
||||
<link rel="stylesheet" type="text/css" href="/public/styles/results.css">
|
||||
<script src="/bower_components/angular/angular.min.js"></script>
|
||||
<script src="/public/scripts/app.js"></script>
|
||||
<script src="/public/scripts/resultsController.js"></script>
|
||||
<script src="/public/scripts/filters.js"></script>
|
||||
</head>
|
||||
<body ng-app="Spaghetti" ng-controller="ResultsCtrl">
|
||||
<h1>Javascript Spaghetti Profiler</h1>
|
||||
|
||||
<div ng-if="undefined">Untangling and counting the spaghettis...</div>
|
||||
|
||||
<div class="ng-cloak">
|
||||
<div>Tested url: <a class="testedUrl" href="phantomasResults.url" target="_blank">{{phantomasResults.url}}</a></div>
|
||||
|
||||
<div ng-if="phantomasResults.error || !phantomasResults.javascript.data">
|
||||
<h2>Error: {{phantomasResults.error}}</h2>
|
||||
<div ng-if="phantomasResults.error == 252">Phantomas timed out</div>
|
||||
<div ng-if="phantomasResults.error == 253">Phantomas config error</div>
|
||||
<div ng-if="phantomasResults.error == 254">Phantomas failed to load page</div>
|
||||
<div ng-if="phantomasResults.error == 255">Phantomas internal error</div>
|
||||
<div ng-if="!phantomasResults.error && !phantomasResults.javascript.data">Javascript execution tree error</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="!phantomasResults.error" class="execution">
|
||||
<h2>Javascript interactions with the DOM</h2>
|
||||
<div class="filters">
|
||||
<div>
|
||||
<input type="checkbox" ng-model="textFilterOn" />
|
||||
Filter by
|
||||
<input type="text" ng-model="textFilter" placeholder="search..." class="textFilter" ng-change="textFilterOn = true" />
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" ng-model="slowRequestsOn" id="slowRequests" />
|
||||
<label for="slowRequests">Requests slower than</label>
|
||||
<input type="number" value="5" min="0" ng-model="slowRequestsLimit" class="slowRequestsLimit"> ms
|
||||
</div>
|
||||
</div>
|
||||
<div class="table">
|
||||
<div class="headers">
|
||||
<div><!-- index --></div>
|
||||
<div>Type</div>
|
||||
<div>Params</div>
|
||||
<div><!-- details --></div>
|
||||
<div>Duration</div>
|
||||
</div>
|
||||
<div ng-repeat="node in phantomasResults.javascript.children"
|
||||
ng-if="(!slowRequestsOn || node.data.time > slowRequestsLimit) && (!textFilterOn || !textFilter.length || node.data.type.indexOf(textFilter) >= 0 || node.data.callDetails.arguments[0].indexOf(textFilter) >= 0)"
|
||||
ng-class="{showingDetails: node.data.showDetails, jsError: node.data.type == 'error'}">
|
||||
<div class="index">{{$index}}</div>
|
||||
<div class="type">{{node.data.type}}</div>
|
||||
<div class="value">{{node.data.callDetails.arguments[0]}}</div>
|
||||
<div class="details">
|
||||
<button ng-click="onNodeDetailsClick(node)">i</button>
|
||||
<div class="detailsOverlay" ng-show="node.data.showDetails">
|
||||
<div class="closeBtn" ng-click="onNodeDetailsClick(node)">✖</div>
|
||||
|
||||
<div ng-if="node.data.callDetails.context.domElement">
|
||||
<h4>Called on DOM element</h4>
|
||||
<div>{{node.data.callDetails.context.domElement}}</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="node.data.callDetails.context.length == 1 && node.data.callDetails.context.firstElementPath">
|
||||
<h4>Called on 1 jQuery element</h4>
|
||||
<div>{{node.data.callDetails.context.firstElementPath}}</div>
|
||||
</div>
|
||||
|
||||
<h4>Backtrace</h4>
|
||||
<div class="table">
|
||||
<div ng-repeat="trace in node.data.parsedBacktrace track by $index">
|
||||
<div>{{trace.fnName || '(anonymous)'}}</div>
|
||||
<div class="trace"><a href="{{trace.filePath}}" title="{{trace.filePath}}" target="_blank">{{trace.fileName || 'HTML'}}</a>:{{trace.line}}</div>
|
||||
</div>
|
||||
<div ng-if="node.data.parsedBacktrace.length == 0">
|
||||
<div>can't find any backtrace :/</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="node.children.length > 0">
|
||||
<h4>Sub processes</h4>
|
||||
<div class="table">
|
||||
<div class="headers">
|
||||
<div><!-- index --></div>
|
||||
<div>Type</div>
|
||||
<div>Params</div>
|
||||
<div>Duration</div>
|
||||
</div>
|
||||
<div ng-repeat="node in node.children">
|
||||
<div class="index">{{$index}}</div>
|
||||
<div class="type">{{node.data.type}}</div>
|
||||
<div class="value">{{node.data.callDetails.arguments[0]}}</div>
|
||||
<div class="duration" ng-if="node.data.time != undefined">{{node.data.time}} ms <div ng-if="node.data.time > slowRequestsLimit" class="warningIcon"></div></div>
|
||||
<div class="duration" ng-if="node.data.time == undefined"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="duration" ng-if="node.data.time != undefined">{{node.data.time}} ms <div ng-if="node.data.time > slowRequestsLimit" class="warningIcon"></div></div>
|
||||
<div class="duration" ng-if="node.data.time == undefined"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>var _phantomas_results = %%RESULTS%%;</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "js-spaghetti-profiler",
|
||||
"dependencies": {
|
||||
"angular": "1.3.0-beta.16"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "jsspaghettiprofiler",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"phantomas": "git+https://git@github.com/gmetais/phantomas.git#jquery-profiler",
|
||||
"express": "^4.6.1",
|
||||
"async": "^0.9.0",
|
||||
"socket.io": "^1.0.6",
|
||||
"body-parser": "^1.5.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
var fs = require('fs');
|
||||
var async = require('async');
|
||||
var express = require('express');
|
||||
var app = express();
|
||||
var server = require('http').createServer(app);
|
||||
var io = require('socket.io').listen(server);
|
||||
var bodyParser = require('body-parser');
|
||||
var phantomas = require('phantomas');
|
||||
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
|
||||
|
||||
// Home page
|
||||
app.get('/', function(req, res) {
|
||||
async.parallel({
|
||||
|
||||
htmlTemplate: function(callback) {
|
||||
fs.readFile('./app/views/index.html', {encoding: 'utf8'}, callback);
|
||||
}
|
||||
|
||||
}, function(err, results) {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.send(results.htmlTemplate);
|
||||
});
|
||||
});
|
||||
|
||||
// Waiting queue page
|
||||
app.post('/launchTest', function(req, res) {
|
||||
// Generate test id
|
||||
var testId = (Date.now()*1000 + Math.round(Math.random()*1000)).toString(36);
|
||||
|
||||
var resultsPath = 'results/' + testId;
|
||||
var phantomasResultsPath = resultsPath + '/results.json';
|
||||
|
||||
var url = req.body.url;
|
||||
if (url.indexOf('http://') !== 0 && url.indexOf('https://') !== 0) {
|
||||
url = 'http://' + url;
|
||||
}
|
||||
|
||||
async.waterfall([
|
||||
|
||||
function htmlTemplate(callback) {
|
||||
fs.readFile('./app/views/launchTest.html', {encoding: 'utf8'}, callback);
|
||||
},
|
||||
|
||||
function sendResponse(html, callback) {
|
||||
|
||||
html = html.replace('%%TEST_URL%%', url);
|
||||
html = html.replace('%%TEST_ID%%', testId);
|
||||
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.send(html);
|
||||
|
||||
callback();
|
||||
},
|
||||
|
||||
function createFolder(callback) {
|
||||
// Create results folder
|
||||
fs.mkdir(resultsPath, callback);
|
||||
},
|
||||
|
||||
function executePhantomas(callback) {
|
||||
|
||||
var options = {
|
||||
timeout: 60,
|
||||
'js-execution-tree': true,
|
||||
reporter: 'json:pretty'
|
||||
};
|
||||
|
||||
console.log('Adding test ' + testId + ' on ' + url + ' to the queue');
|
||||
|
||||
var task = {
|
||||
testId: testId,
|
||||
url: url,
|
||||
options: options
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(task, null, 4));
|
||||
|
||||
taskQueue.push(task, callback);
|
||||
},
|
||||
|
||||
function writeResults(json, resultsObject, callback) {
|
||||
console.log('Saving Phantomas results file to ' + phantomasResultsPath);
|
||||
fs.writeFile(phantomasResultsPath, JSON.stringify(json, null, 4), callback);
|
||||
}
|
||||
|
||||
], function(err) {
|
||||
if (err) {
|
||||
console.log('An error occured while launching the phantomas test : ', err);
|
||||
|
||||
fs.writeFile(phantomasResultsPath, JSON.stringify({url: url, error: err}, null, 4), function(err) {
|
||||
if (err) {
|
||||
console.log('Could not even write an error message on file ' + phantomasResultsPath);
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Results page
|
||||
app.get('/results/:testId', function(req, res) {
|
||||
|
||||
var testId = req.params.testId;
|
||||
var resultsPath = 'results/' + testId;
|
||||
var phantomasResultsPath = resultsPath + '/results.json';
|
||||
|
||||
console.log('Opening test ' + testId + ' results as HTML');
|
||||
|
||||
async.parallel({
|
||||
|
||||
htmlTemplate: function(callback) {
|
||||
fs.readFile('./app/views/results.html', {encoding: 'utf8'}, callback);
|
||||
},
|
||||
|
||||
phantomasResults: function(callback) {
|
||||
fs.readFile(phantomasResultsPath, {encoding: 'utf8'}, callback);
|
||||
}
|
||||
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
return res.status(404).send('Sorry, test not found...');
|
||||
}
|
||||
|
||||
var html = results.htmlTemplate;
|
||||
html = html.replace('%%RESULTS%%', results.phantomasResults);
|
||||
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.send(html);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Static files
|
||||
app.use('/public', express.static(__dirname + '/app/public'));
|
||||
app.use('/bower_components', express.static(__dirname + '/bower_components'));
|
||||
|
||||
|
||||
// Socket.io
|
||||
io.on('connection', function(socket){
|
||||
socket.on('waiting', function(testId) {
|
||||
console.log('User waiting for test id ' + testId);
|
||||
socket.testId = testId;
|
||||
|
||||
// Check task position in queue
|
||||
var positionInQueue = -1;
|
||||
if (taskQueue.length() > 0) {
|
||||
taskQueue.tasks.forEach(function(task, index) {
|
||||
if (task.data.testId === testId) {
|
||||
positionInQueue = index;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (positionInQueue >= 0) {
|
||||
socket.emit('position', positionInQueue);
|
||||
} else if (currentTask && currentTask.testId === testId) {
|
||||
socket.emit('running');
|
||||
} else {
|
||||
// Find in results files
|
||||
var exists = fs.exists('results/' + testId + '/results.json', function(exists) {
|
||||
if (exists) {
|
||||
// TODO : use eventEmitter to make sure the file is completly written on disk
|
||||
setTimeout(function() {
|
||||
socket.emit('complete');
|
||||
}, 1000);
|
||||
} else {
|
||||
socket.emit('404');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Creating a queue and defining the worker function
|
||||
var currentTask = null;
|
||||
var taskQueue = async.queue(function queueWorker(task, callback) {
|
||||
|
||||
currentTask = task;
|
||||
console.log('Starting test ' + task.testId);
|
||||
|
||||
// It's time to launch the test!!!
|
||||
phantomas(task.url, task.options, function(err, json, results) {
|
||||
console.log('Test ' + task.testId + ' complete');
|
||||
currentTask = null;
|
||||
callback(err, json, results);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Launch the server
|
||||
server.listen(8383, function() {
|
||||
console.log('Listening on port %d', server.address().port);
|
||||
});
|
||||
Reference in New Issue
Block a user