Explorar el Código

Add a progress bar on the UI

Gaël Métais hace 4 años
padre
commit
bd9cb2e257

+ 13 - 0
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;
+}

+ 9 - 2
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 {

+ 15 - 0
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;
 }

+ 10 - 1
front/src/views/queue.html

@@ -17,7 +17,16 @@
     </div>
     <div ng-if="status.statusCode == 'running'">
         <div class="status">Test is running...</div>
-        <p class="statusSubMessage">(auto-refresh activated)</p>
+        <div class="progress">
+            <div class="progressBarEmpty">
+                <div class="progressBarFilled" ng-style="{'width': (progress.estimatedProgress*100) + '%'}"></div>
+            </div>
+        </div>
+        <p class="statusSubMessage" ng-if="!progress">(Phantomas launched)</p>
+        <p class="statusSubMessage" ng-if="progress.milestone == 'domReady'">(DOM Ready fired)</p>
+        <p class="statusSubMessage" ng-if="progress.milestone == 'domComplete'">(page loaded, waiting for late requests)</p>
+        <p class="statusSubMessage" ng-if="progress.milestone == 'phantomas'">(now simulating compression, optimization and minification)</p>
+        <p class="statusSubMessage" ng-if="progress.milestone == 'redownload'">(calculating score and retreaving screenshot)</p>
     </div>
     <div ng-if="status.statusCode == 'complete'">
         <div class="status">Test complete</div>

+ 4 - 0
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);
             });

+ 36 - 1
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);

+ 7 - 3
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);
+            });
 
         })
 

+ 10 - 0
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];
 

+ 6 - 0
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;
     };
 };

+ 12 - 3
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;
         }