diff --git a/front/src/css/queue.css b/front/src/css/queue.css index 094ee24..64237d5 100644 --- a/front/src/css/queue.css +++ b/front/src/css/queue.css @@ -6,3 +6,16 @@ font-size: 0.8em; margin-bottom: 6em; } +.progressBarEmpty { + width: 90%; + max-width: 300px; + margin: 1em auto; + padding: 0.05em; + border: 1px solid #ffa319; +} +.progressBarFilled { + width: 5%; + height: 0.5em; + background: #ffa319; + transition: width 2s ease-out; +} diff --git a/front/src/js/controllers/queueCtrl.js b/front/src/js/controllers/queueCtrl.js index 17a3820..f62775d 100644 --- a/front/src/js/controllers/queueCtrl.js +++ b/front/src/js/controllers/queueCtrl.js @@ -9,15 +9,22 @@ queueCtrl.controller('QueueCtrl', ['$scope', '$routeParams', '$location', 'Runs' Runs.get({runId: $scope.runId}, function(data) { $scope.url = data.params.url; $scope.status = data.status; + $scope.progress = data.progress; $scope.notFound = false; $scope.connectionLost = false; - if (data.status.statusCode === 'running' || data.status.statusCode === 'awaiting') { + if (data.status.statusCode === 'awaiting') { numberOfTries ++; - // Retrying in 2 seconds (and increasing the delay a bit more each time) + // Retrying every 2 seconds (and increasing the delay a bit more each time) setTimeout(getRunStatus, 2000 + (numberOfTries * 100)); + } else if (data.status.statusCode === 'running') { + numberOfTries ++; + + // Retrying every second or so + setTimeout(getRunStatus, 1000 + (numberOfTries * 10)); + } else if (data.status.statusCode === 'complete') { $location.path('/result/' + $scope.runId).replace(); } else { diff --git a/front/src/less/queue.less b/front/src/less/queue.less index f8d2cb2..41212c5 100644 --- a/front/src/less/queue.less +++ b/front/src/less/queue.less @@ -6,4 +6,19 @@ .statusSubMessage { font-size: 0.8em; margin-bottom: 6em; +} + +.progressBarEmpty { + width: 90%; + max-width: 300px; + margin: 1em auto; + padding: 0.05em; + border: 1px solid #ffa319; +} + +.progressBarFilled { + width: 5%; + height: 0.5em; + background: #ffa319; + transition: width 2s ease-out; } \ No newline at end of file diff --git a/front/src/views/queue.html b/front/src/views/queue.html index 204b332..e86b249 100644 --- a/front/src/views/queue.html +++ b/front/src/views/queue.html @@ -17,7 +17,16 @@
Test is running...
-

(auto-refresh activated)

+
+
+
+
+
+

(Phantomas launched)

+

(DOM Ready fired)

+

(page loaded, waiting for late requests)

+

(now simulating compression, optimization and minification)

+

(calculating score and retreaving screenshot)

Test complete
diff --git a/lib/index.js b/lib/index.js index 81819f4..9064046 100644 --- a/lib/index.js +++ b/lib/index.js @@ -24,9 +24,13 @@ var yellowLabTools = function(url, options) { }; var runner = new Runner(params) + + .progress(deferred.notify) + .then(function(data) { deferred.resolve(data); }) + .fail(function(err) { deferred.reject(err); }); diff --git a/lib/runner.js b/lib/runner.js index 29332fb..33389e5 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -24,7 +24,29 @@ var Runner = function(params) { // Execute Phantomas first phantomasWrapper.execute(data) + // For the progress bar + .progress(function(event) { + if (event === 'domReady') { + deferred.notify({ + estimatedProgress: 0.15, + milestone: 'domReady' + }); + } + if (event === 'domComplete') { + deferred.notify({ + estimatedProgress: 0.25, + milestone: 'domComplete' + }); + } + }) + .then(function(phantomasResults) { + // For the progress bar + deferred.notify({ + estimatedProgress: 0.4, + milestone: 'phantomas' + }); + data.toolsResults.phantomas = phantomasResults; // Mix all DOM Access metrics together @@ -37,12 +59,25 @@ var Runner = function(params) { data = mediaQueriesChecker.analyzeMediaQueries(data); // Redownload every file - return redownload.recheckAllFiles(data); + return redownload.recheckAllFiles(data) + + .progress(function(redownloadedProgress) { + deferred.notify({ + estimatedProgress: 0.4 + redownloadedProgress * 0.55, + milestone: 'phantomas' + }); + }); }) .then(function(data) { + // For the progress bar + deferred.notify({ + estimatedProgress: 0.99, + milestone: 'redownload' + }); + // Rules checker var policies = require('./metadata/policies'); data.rules = rulesChecker.check(data, policies); diff --git a/lib/server/controllers/apiController.js b/lib/server/controllers/apiController.js index d6f701f..3e057ec 100644 --- a/lib/server/controllers/apiController.js +++ b/lib/server/controllers/apiController.js @@ -84,11 +84,15 @@ var ApiController = function(app) { authPass: run.params.authPass, blockDomain: run.params.blockDomain, allowDomain: run.params.allowDomain, - noExternals: run.params.noExternals, - phantomasEngine: serverSettings.phantomasEngine + noExternals: run.params.noExternals }; - return ylt(run.params.url, runOptions); + return ylt(run.params.url, runOptions) + + // Update the progress bar on each progress + .progress(function(progress) { + runsDatastore.updateRunProgress(run.runId, progress); + }); }) diff --git a/lib/server/datastores/runsDatastore.js b/lib/server/datastores/runsDatastore.js index 8104b68..fd82fcc 100644 --- a/lib/server/datastores/runsDatastore.js +++ b/lib/server/datastores/runsDatastore.js @@ -42,6 +42,16 @@ function RunsDatastore() { }; + // When the test is launched, set the progress bar + this.updateRunProgress = function(runId, progress) { + var run = runs[runId]; + + run.progress = progress; + + runs[runId] = run; + }; + + this.markAsComplete = function(runId) { var run = runs[runId]; diff --git a/lib/tools/phantomas/phantomasWrapper.js b/lib/tools/phantomas/phantomasWrapper.js index 21af510..c75c648 100644 --- a/lib/tools/phantomas/phantomasWrapper.js +++ b/lib/tools/phantomas/phantomasWrapper.js @@ -79,6 +79,12 @@ var PhantomasWrapper = function() { deferred.reject('Phantomas failed: ' + res.message); }); + promise.on('milestone', function(event) { + if (event === 'domReady' || event === 'domComplete') { + deferred.notify(event); + } + }); + return deferred.promise; }; }; diff --git a/lib/tools/redownload/redownload.js b/lib/tools/redownload/redownload.js index cb1adce..f869b75 100644 --- a/lib/tools/redownload/redownload.js +++ b/lib/tools/redownload/redownload.js @@ -33,6 +33,7 @@ var Redownload = function() { function recheckAllFiles(data) { var startTime = Date.now(); debug('Redownload started'); + var deferred = Q.defer(); var requestsOffenders = data.toolsResults.phantomas.offenders.requests; @@ -43,6 +44,9 @@ var Redownload = function() { var requestsList = mergeOffenders(requestsOffenders, gzipOffenders, postOffenders, notFoundOffenders, redirectOffenders); + var totalCount = requestsList.length; + var doneCount = 0; + var httpAuth = null; if (data.params && data.params.options && data.params.options.authUser && data.params.options.authPass) { httpAuth = { @@ -89,6 +93,11 @@ var Redownload = function() { .then(function(newEntry) { debug('File %s - Redownloaded, optimized, minified, compressed, analyzed: done', entry.url); + + // For the progress bar + doneCount ++; + deferred.notify(doneCount/totalCount); + callback(null, newEntry); }) @@ -745,9 +754,9 @@ var Redownload = function() { function detectWordPress(requests) { // Check the first file only - if (requests[0].isHTML - && requests[0].weightCheck.bodyBuffer - && requests[0].weightCheck.bodyBuffer.indexOf('/wp-content/') > 0) { + if (requests[0].isHTML && + requests[0].weightCheck.bodyBuffer && + requests[0].weightCheck.bodyBuffer.indexOf('/wp-content/') > 0) { return true; }