Browse Source

Share score button + Restart test button

Gaël Métais 10 years ago
parent
commit
a141122fbd

+ 56 - 63
front/src/css/dashboard.css

@@ -1,8 +1,49 @@
 .testedUrl {
 .testedUrl {
   color: inherit;
   color: inherit;
 }
 }
-h4 {
-  margin-bottom: 0.5em;
+.summary {
+  text-align: center;
+}
+.globalScore {
+  margin-bottom: 3em;
+}
+.globalScore .globalGrade {
+  margin: 0.5 auto;
+  width: 2.5em;
+  height: 2.5em;
+  line-height: 2.5em;
+  border-radius: 0.5em;
+  font-size: 3em;
+  font-weight: bold;
+  vertical-align: middle;
+}
+.globalScore .on100 {
+  font-size: 1.2em;
+  font-weight: bold;
+  margin: 0.5em 0 1em;
+}
+.globalScore .tweetText {
+  color: #333;
+  background: #F2F2F2;
+  border: none;
+  width: 25em;
+  padding: 0.4em;
+  border-radius: 0.5em;
+  box-shadow: 0.05em 0.1em 0 0 #999;
+}
+.globalScore .tweetButton,
+.globalScore .linkedinButton {
+  color: #333;
+  background: #F2F2F2;
+  margin-right: 0;
+}
+.globalScore .tweetButton:hover,
+.globalScore .linkedinButton:hover {
+  color: #F2F2F2;
+  background: #e74c3c;
+}
+.globalScore input {
+  font-size: 0.9em;
 }
 }
 .notations {
 .notations {
   display: table;
   display: table;
@@ -101,66 +142,18 @@ h4 {
 .notations .criteria .icon-question {
 .notations .criteria .icon-question {
   color: transparent;
   color: transparent;
 }
 }
-/**** NgModal popin (have a look inside bower_components) ****/
-.ng-modal {
-  position: fixed;
-  z-index: 9999;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  text-align: left;
-}
-.ng-modal-overlay {
-  position: absolute;
-  z-index: 9999;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  background-color: #000;
-  opacity: 0.5;
-}
-.ng-modal-dialog {
-  z-index: 10000;
-  position: absolute;
-  top: 50%;
-  left: 50%;
-  width: 50%;
-  transform: translate(-50%, -50%);
-  -webkit-transform: translate(-50%, -50%);
-  background-color: #fff;
-  padding: 10px;
-  border: 3px solid #f1c40f;
-  border-radius: 0.5em;
-  color: #000;
+.fromShare {
+  margin-bottom: 3em;
 }
 }
-.ng-modal-dialog-content {
-  overflow-x: hidden;
-  overflow-y: scroll;
-  word-wrap: break-word;
-  max-height: 20em;
-  font-weight: normal;
-  white-space: normal;
-}
-.ng-modal-close {
-  position: absolute;
-  top: 3px;
-  right: 5px;
-  cursor: pointer;
-  font-size: 120%;
-  padding: 5px;
-  display: inline-block;
-}
-.ng-modal-close-x {
-  font-weight: bold;
-  font-family: Arial, sans-serif;
-}
-.ng-modal-title {
-  font-weight: bold;
-  font-size: 1.5em;
-  display: block;
-  margin-bottom: 10px;
-  padding-bottom: 7px;
-  border-bottom: solid 1px #999;
+.fromShare a {
+  font-size: 1em;
+  padding: 0.3em 0.5em;
+  margin: 0.5em;
+  line-height: 2em;
+  border: 0 solid;
+  border-radius: 0.5em;
+  box-shadow: 0.1em 0.2em 0 0 #5e2846;
+  background: #e74c3c;
+  color: #fff;
+  text-decoration: none;
 }
 }

+ 19 - 5
front/src/css/main.css

@@ -46,7 +46,8 @@ h1 span {
   cursor: pointer;
   cursor: pointer;
   text-decoration: none;
   text-decoration: none;
 }
 }
-.resultsMenu .back {
+.resultsMenu .menuItem.back,
+.resultsMenu .menuItem.restart {
   color: #413;
   color: #413;
   border-color: #413;
   border-color: #413;
 }
 }
@@ -137,7 +138,7 @@ h1 span {
   -webkit-font-smoothing: antialiased;
   -webkit-font-smoothing: antialiased;
 }
 }
 .icon-lab:before {
 .icon-lab:before {
-  content: "\e003";
+  content: "\e004";
 }
 }
 .icon-question {
 .icon-question {
   font-family: "fontsmith-icons";
   font-family: "fontsmith-icons";
@@ -176,7 +177,7 @@ h1 span {
   -webkit-font-smoothing: antialiased;
   -webkit-font-smoothing: antialiased;
 }
 }
 .icon-back:before {
 .icon-back:before {
-  content: "\e005";
+  content: "\e006";
 }
 }
 .icon-summary {
 .icon-summary {
   font-family: "fontsmith-icons";
   font-family: "fontsmith-icons";
@@ -189,7 +190,7 @@ h1 span {
   -webkit-font-smoothing: antialiased;
   -webkit-font-smoothing: antialiased;
 }
 }
 .icon-summary:before {
 .icon-summary:before {
-  content: "\e002";
+  content: "\e003";
 }
 }
 .icon-spaghetti {
 .icon-spaghetti {
   font-family: "fontsmith-icons";
   font-family: "fontsmith-icons";
@@ -202,5 +203,18 @@ h1 span {
   -webkit-font-smoothing: antialiased;
   -webkit-font-smoothing: antialiased;
 }
 }
 .icon-spaghetti:before {
 .icon-spaghetti:before {
-  content: "\e004";
+  content: "\e005";
+}
+.icon-loop {
+  font-family: "fontsmith-icons";
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+  -webkit-font-smoothing: antialiased;
+}
+.icon-loop:before {
+  content: "\e002";
 }
 }

+ 7 - 1
front/src/css/timeline.css

@@ -1,4 +1,7 @@
 /* Timeline colors, related to Window Performances */
 /* Timeline colors, related to Window Performances */
+.execution {
+  text-align: center;
+}
 .timeline {
 .timeline {
   margin: 2em 0 5em;
   margin: 2em 0 5em;
 }
 }
@@ -117,9 +120,12 @@
   border-radius: 0.2em;
   border-radius: 0.2em;
 }
 }
 .filters {
 .filters {
-  margin: 1em 0;
+  margin: 1em auto;
   padding: 0.5em;
   padding: 0.5em;
+  min-width: 30em;
+  width: 30%;
   border: 1px dotted #aaa;
   border: 1px dotted #aaa;
+  text-align: left;
 }
 }
 .slowRequestsLimit {
 .slowRequestsLimit {
   width: 3em;
   width: 3em;

BIN
front/src/fonts/icons.woff


File diff suppressed because it is too large
+ 0 - 0
front/src/fonts/svg-icons/loop.svg


+ 40 - 1
front/src/js/controllers/dashboardCtrl.js

@@ -1,8 +1,9 @@
 var dashboardCtrl = angular.module('dashboardCtrl', ['resultsFactory', 'menuService']);
 var dashboardCtrl = angular.module('dashboardCtrl', ['resultsFactory', 'menuService']);
 
 
-dashboardCtrl.controller('DashboardCtrl', ['$scope', '$rootScope', '$routeParams', '$location', 'Results', 'Menu', function($scope, $rootScope, $routeParams, $location, Results, Menu) {
+dashboardCtrl.controller('DashboardCtrl', ['$scope', '$rootScope', '$routeParams', '$location', 'Results', 'Runs', 'Menu', function($scope, $rootScope, $routeParams, $location, Results, Runs, Menu) {
     $scope.runId = $routeParams.runId;
     $scope.runId = $routeParams.runId;
     $scope.Menu = Menu.setCurrentPage('dashboard', $scope.runId);
     $scope.Menu = Menu.setCurrentPage('dashboard', $scope.runId);
+    $scope.fromSocialShare = $location.search().share;
     
     
     function loadResults() {
     function loadResults() {
         // Load result if needed
         // Load result if needed
@@ -10,15 +11,53 @@ dashboardCtrl.controller('DashboardCtrl', ['$scope', '$rootScope', '$routeParams
             Results.get({runId: $routeParams.runId}, function(result) {
             Results.get({runId: $routeParams.runId}, function(result) {
                 $rootScope.loadedResult = result;
                 $rootScope.loadedResult = result;
                 $scope.result = result;
                 $scope.result = result;
+                init();
             });
             });
         } else {
         } else {
             $scope.result = $rootScope.loadedResult;
             $scope.result = $rootScope.loadedResult;
+            init();
         }
         }
     }
     }
 
 
+    function init() {
+        $scope.globalScore = Math.max($scope.result.scoreProfiles.generic.globalScore, 0);
+        $scope.tweetText = 'My website\'s score is ' + $scope.globalScore + '/100 on #YellowLabTools!';
+    }
+
     $scope.showRulePage = function(ruleName) {
     $scope.showRulePage = function(ruleName) {
         $location.path('/result/' + $scope.runId + '/rule/' + ruleName);
         $location.path('/result/' + $scope.runId + '/rule/' + ruleName);
     };
     };
 
 
+    $scope.testAgain = function() {
+        Runs.save({
+                url: $scope.result.params.url,
+                waitForResponse: false
+            }, function(data) {
+                $location.path('/queue/' + data.runId);
+            });
+    };
+
+    /// When comming from a social shared link, the user needs to click on "See full report" button to display the full dashboard.
+    $scope.seeFullReport = function() {
+        $scope.fromSocialShare = false;
+        $location.search({});
+    };
+
+    $scope.shareOnTwitter = function(message) {
+        openSocialPopup('https://twitter.com/intent/tweet?url=' + document.URL + '%3Fshare&text=' + encodeURIComponent(message));
+    };
+
+    $scope.shareOnLinkedin = function(message) {
+        openSocialPopup('https://www.linkedin.com/shareArticle?mini=true&url=' + document.URL + '%3Fshare&title=' + encodeURIComponent(message) + '&summary=' + encodeURIComponent('YellowLabTools is a free online tool that analyzes performance and front-end quality of a webpage.'));
+    };
+
+    function openSocialPopup(url) {
+        var winHeight = 400;
+        var winWidth = 600;
+        var winTop = (screen.height / 2) - (winHeight / 2);
+        var winLeft = (screen.width / 2) - (winWidth / 2);
+        window.open(url, 'sharer', 'top=' + winTop + ',left=' + winLeft + ',toolbar=0,status=0,width=' + winWidth + ',height=' + winHeight);
+    }
+
     loadResults();
     loadResults();
 }]);
 }]);

+ 10 - 1
front/src/js/controllers/ruleCtrl.js

@@ -1,6 +1,6 @@
 var ruleCtrl = angular.module('ruleCtrl', []);
 var ruleCtrl = angular.module('ruleCtrl', []);
 
 
-ruleCtrl.controller('RuleCtrl', ['$scope', '$rootScope', '$routeParams', '$location', '$sce', 'Menu', 'Results', function($scope, $rootScope, $routeParams, $location, $sce, Menu, Results) {
+ruleCtrl.controller('RuleCtrl', ['$scope', '$rootScope', '$routeParams', '$location', '$sce', 'Menu', 'Results', 'Runs', function($scope, $rootScope, $routeParams, $location, $sce, Menu, Results, Run) {
     $scope.runId = $routeParams.runId;
     $scope.runId = $routeParams.runId;
     $scope.policyName = $routeParams.policy;
     $scope.policyName = $routeParams.policy;
     $scope.Menu = Menu.setCurrentPage(null, $scope.runId);
     $scope.Menu = Menu.setCurrentPage(null, $scope.runId);
@@ -29,5 +29,14 @@ ruleCtrl.controller('RuleCtrl', ['$scope', '$rootScope', '$routeParams', '$locat
         $location.path('/result/' + $scope.runId);
         $location.path('/result/' + $scope.runId);
     };
     };
 
 
+    $scope.testAgain = function() {
+        Runs.save({
+                url: $scope.result.params.url,
+                waitForResponse: false
+            }, function(data) {
+                $location.path('/queue/' + data.runId);
+            });
+    };
+
     loadResults();
     loadResults();
 }]);
 }]);

+ 10 - 1
front/src/js/controllers/timelineCtrl.js

@@ -1,6 +1,6 @@
 var timelineCtrl = angular.module('timelineCtrl', []);
 var timelineCtrl = angular.module('timelineCtrl', []);
 
 
-timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams', '$location', '$timeout', 'Menu', 'Results', function($scope, $rootScope, $routeParams, $location, $timeout, Menu, Results) {
+timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams', '$location', '$timeout', 'Menu', 'Results', 'Runs', function($scope, $rootScope, $routeParams, $location, $timeout, Menu, Results, Runs) {
     $scope.runId = $routeParams.runId;
     $scope.runId = $routeParams.runId;
     $scope.Menu = Menu.setCurrentPage('timeline', $scope.runId);
     $scope.Menu = Menu.setCurrentPage('timeline', $scope.runId);
 
 
@@ -131,6 +131,15 @@ timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams',
         $location.path('/result/' + $scope.runId);
         $location.path('/result/' + $scope.runId);
     };
     };
 
 
+    $scope.testAgain = function() {
+        Runs.save({
+                url: $scope.result.params.url,
+                waitForResponse: false
+            }, function(data) {
+                $location.path('/queue/' + data.runId);
+            });
+    };
+
     loadResults();
     loadResults();
 
 
 }]);
 }]);

+ 57 - 66
front/src/less/dashboard.less

@@ -2,8 +2,48 @@
     color: inherit;
     color: inherit;
 }
 }
 
 
-h4 {
-    margin-bottom: 0.5em;
+.summary {
+    text-align: center;
+}
+
+.globalScore {
+    margin-bottom: 3em;
+    .globalGrade {
+        margin: 0.5 auto;
+        width: 2.5em;
+        height: 2.5em;
+        line-height: 2.5em;
+        border-radius: 0.5em;
+        font-size: 3em;
+        font-weight: bold;
+        vertical-align: middle;
+    }
+    .on100 {
+        font-size: 1.2em;
+        font-weight: bold;
+        margin: 0.5em 0 1em;
+    }
+    .tweetText {
+        color: #333;
+        background: #F2F2F2;
+        border: none;
+        width: 25em;
+        padding: 0.4em;
+        border-radius: 0.5em;
+        box-shadow: 0.05em 0.1em 0 0 #999;
+    }
+    .tweetButton, .linkedinButton {
+        color: #333;
+        background: #F2F2F2;
+        margin-right: 0;
+        &:hover {
+            color: #F2F2F2;
+            background: #e74c3c;
+        }
+    }
+    input {
+        font-size: 0.9em;
+    }
 }
 }
 
 
 .notations {
 .notations {
@@ -93,67 +133,18 @@ h4 {
     color: transparent;
     color: transparent;
 }
 }
 
 
-
-/**** NgModal popin (have a look inside bower_components) ****/
-.ng-modal {
-    position: fixed;
-    z-index: 9999;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    text-align: left;
-}
-.ng-modal-overlay {
-    position: absolute;
-    z-index: 9999;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    background-color: #000;
-    opacity: 0.5;
-}
-.ng-modal-dialog {
-    z-index: 10000;
-    position: absolute;
-    top: 50%;
-    left: 50%;
-    width: 50%;
-    transform: translate(-50%, -50%);
-    -webkit-transform: translate(-50%, -50%);
-    background-color: #fff;
-    padding: 10px;
-    border: 3px solid #f1c40f;
-    border-radius: 0.5em;
-    color: #000;
-}
-.ng-modal-dialog-content {
-    overflow-x: hidden;
-    overflow-y: scroll;
-    word-wrap: break-word;
-    max-height: 20em;
-    font-weight: normal;
-    white-space: normal;
-}
-.ng-modal-close {
-    position: absolute;
-    top: 3px;
-    right: 5px;
-    cursor: pointer;
-    font-size: 120%;
-    padding: 5px;
-    display: inline-block;
-}
-.ng-modal-close-x {
-    font-weight: bold;
-    font-family: Arial, sans-serif;
-}
-.ng-modal-title {
-    font-weight: bold;
-    font-size: 1.5em;
-    display: block;
-    margin-bottom: 10px;
-    padding-bottom: 7px;
-    border-bottom: solid 1px #999;
-}
+.fromShare {
+    margin-bottom: 3em;
+    a {
+        font-size: 1em;
+        padding: 0.3em 0.5em;
+        margin: 0.5em;
+        line-height: 2em;
+        border: 0 solid;
+        border-radius: 0.5em;
+        box-shadow: 0.1em 0.2em 0 0 #5e2846;
+        background: #e74c3c;
+        color: #fff;
+        text-decoration: none;
+    }
+}

+ 14 - 11
front/src/less/icons.less

@@ -1,21 +1,24 @@
-@list-font-family: "fontsmith-icons";
-@list-value: "\e002";
-@list: '"fontsmith-icons"' '"\\e002"';
-@bars-font-family: "fontsmith-icons";
-@bars-value: "\e004";
-@bars: '"fontsmith-icons"' '"\\e004"';
 @lab-font-family: "fontsmith-icons";
 @lab-font-family: "fontsmith-icons";
-@lab-value: "\e003";
-@lab: '"fontsmith-icons"' '"\\e003"';
+@lab-value: "\e004";
+@lab: '"fontsmith-icons"' '"\\e004"';
+@list-font-family: "fontsmith-icons";
+@list-value: "\e003";
+@list: '"fontsmith-icons"' '"\\e003"';
+@loop-font-family: "fontsmith-icons";
+@loop-value: "\e002";
+@loop: '"fontsmith-icons"' '"\\e002"';
 @warning-font-family: "fontsmith-icons";
 @warning-font-family: "fontsmith-icons";
 @warning-value: "\e000";
 @warning-value: "\e000";
 @warning: '"fontsmith-icons"' '"\\e000"';
 @warning: '"fontsmith-icons"' '"\\e000"';
-@arrow-left3-font-family: "fontsmith-icons";
-@arrow-left3-value: "\e005";
-@arrow-left3: '"fontsmith-icons"' '"\\e005"';
 @question-font-family: "fontsmith-icons";
 @question-font-family: "fontsmith-icons";
 @question-value: "\e001";
 @question-value: "\e001";
 @question: '"fontsmith-icons"' '"\\e001"';
 @question: '"fontsmith-icons"' '"\\e001"';
+@bars-font-family: "fontsmith-icons";
+@bars-value: "\e005";
+@bars: '"fontsmith-icons"' '"\\e005"';
+@arrow-left3-font-family: "fontsmith-icons";
+@arrow-left3-value: "\e006";
+@arrow-left3: '"fontsmith-icons"' '"\\e006"';
 
 
 .icon-font-family(@char) {
 .icon-font-family(@char) {
   font-family: ~`@{char}[0]`;
   font-family: ~`@{char}[0]`;

+ 7 - 4
front/src/less/main.less

@@ -41,10 +41,10 @@ h1 span {
     border-radius: 0.5em;
     border-radius: 0.5em;
     cursor: pointer;
     cursor: pointer;
     text-decoration: none;
     text-decoration: none;
-}
-.resultsMenu .back {
-    color: #413;
-    border-color: #413;
+    &.back, &.restart {
+        color: #413;
+        border-color: #413;
+    }
 }
 }
 .resultsMenu .menuItem div {
 .resultsMenu .menuItem div {
     padding-top: 0.5em;
     padding-top: 0.5em;
@@ -146,4 +146,7 @@ h1 span {
 }
 }
 .icon-spaghetti {
 .icon-spaghetti {
     .icon(@bars);
     .icon(@bars);
+}
+.icon-loop {
+    .icon(@loop);
 }
 }

+ 7 - 1
front/src/less/timeline.less

@@ -10,6 +10,9 @@
 @domInteractiveColor: #FFE433;
 @domInteractiveColor: #FFE433;
 @domInteractiveBg: #FFFCCC;
 @domInteractiveBg: #FFFCCC;
 
 
+.execution {
+    text-align: center;
+}
 
 
 .timeline {
 .timeline {
     margin: 2em 0 5em;
     margin: 2em 0 5em;
@@ -130,9 +133,12 @@
 }
 }
 
 
 .filters {
 .filters {
-    margin: 1em 0;
+    margin: 1em auto;
     padding: 0.5em;
     padding: 0.5em;
+    min-width: 30em;
+    width: 30%;
     border: 1px dotted #aaa;
     border: 1px dotted #aaa;
+    text-align: left;
 }
 }
 
 
 .slowRequestsLimit {
 .slowRequestsLimit {

+ 25 - 3
front/src/views/dashboard.html

@@ -1,14 +1,30 @@
 <div ng-include="'/front/views/resultSubHeader.html'"></div>
 <div ng-include="'/front/views/resultSubHeader.html'"></div>
 <div class="summary board">
 <div class="summary board">
-    <h2>Grades</h2>
+    
+    <h2> Global score</h2>
+    <div class="globalScore" ng-if="globalScore === 0 || globalScore > 0">
+        <div class="globalScoreDisplay">
+            <grade score="result.scoreProfiles.generic.globalScore" class="globalGrade"></grade>
+            <div class="on100">{{globalScore}}/100</div>
+        </div>
+        <div class="tweet" ng-if="!fromSocialShare">
+            <form ng-submit="sendTweet()">
+                <input type="text" class="tweetText" ng-model="tweetText">
+                <input type="submit" class="tweetButton" value="Tweet this!" ng-click="shareOnTwitter(tweetText)">
+                <input type="submit" class="linkedinButton" value="LinkedIn" ng-click="shareOnLinkedin(tweetText)">
+            </form>
+        </div>
+    </div>
 
 
-    <div class="notations">
+    <h2 ng-if="!fromSocialShare">Score details</h2>
+    <div ng-if="!fromSocialShare" class="notations">
         <div ng-repeat="category in result.scoreProfiles.generic.categories">
         <div ng-repeat="category in result.scoreProfiles.generic.categories">
             <grade score="category.categoryScore" class="categoryScore"></grade>
             <grade score="category.categoryScore" class="categoryScore"></grade>
             <div class="category">{{category.label}}</div>
             <div class="category">{{category.label}}</div>
             <div class="criteria">
             <div class="criteria">
                 <div class="table" title="Click to see details">
                 <div class="table" title="Click to see details">
-                    <div ng-repeat="ruleName in category.rules" 
+                    <div ng-repeat="ruleName in category.rules"
+                         ng-if="result.rules[ruleName]"
                          ng-init="rule = result.rules[ruleName]"
                          ng-init="rule = result.rules[ruleName]"
                          ng-class="{'warning': rule.abnormal}"
                          ng-class="{'warning': rule.abnormal}"
                          ng-click="showRulePage(ruleName)">
                          ng-click="showRulePage(ruleName)">
@@ -28,4 +44,10 @@
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>
+
+    <div class="fromShare" ng-if="fromSocialShare">
+        <p>Yellow Lab Tools is a free online tool that analyzes performance and front-end quality.</p>
+        <a href="" ng-click="seeFullReport()">See the full report for this page</a>
+        <a href="/">Test another webpage</a>
+    </div>
 </div>
 </div>

+ 1 - 1
front/src/views/index.html

@@ -1,6 +1,6 @@
 <h2 class="promess">Free online test to help speeding up <b>heavy</b> web pages</h2>
 <h2 class="promess">Free online test to help speeding up <b>heavy</b> web pages</h2>
 
 
 <form ng-submit="launchTest()" >
 <form ng-submit="launchTest()" >
-    <input type="text"ng-model="url" placeholder="http://www.mysite.com" class="url" />
+    <input type="text" name="url" ng-model="url" placeholder="http://www.mysite.com" class="url" />
     <input type="submit" value="Launch test" class="launchBtn" ng-class="{disabled: !url}" />
     <input type="submit" value="Launch test" class="launchBtn" ng-class="{disabled: !url}" />
 </form>
 </form>

+ 1 - 0
front/src/views/resultSubHeader.html

@@ -2,6 +2,7 @@
 
 
 <div class="resultsMenu">
 <div class="resultsMenu">
     <a class="menuItem back" href="/"><div class="icon-back"></div><span>New test<span></a>
     <a class="menuItem back" href="/"><div class="icon-back"></div><span>New test<span></a>
+    <a class="menuItem restart" href="" ng-click="testAgain()"><div class="icon-loop"></div><span>Test again<span></a>
     <div class="menuItem" ng-class="{active: Menu.getCurrentPage() == 'dashboard'}" ng-click="Menu.changePage('dashboard')"><div class="icon-summary"></div><span>Dashboard</span></div>
     <div class="menuItem" ng-class="{active: Menu.getCurrentPage() == 'dashboard'}" ng-click="Menu.changePage('dashboard')"><div class="icon-summary"></div><span>Dashboard</span></div>
     <div class="menuItem" ng-class="{active: Menu.getCurrentPage() == 'timeline'}" ng-click="Menu.changePage('timeline')"><div class="icon-spaghetti"></div><span>JS Timeline</span></div>
     <div class="menuItem" ng-class="{active: Menu.getCurrentPage() == 'timeline'}" ng-click="Menu.changePage('timeline')"><div class="icon-spaghetti"></div><span>JS Timeline</span></div>
 </div>
 </div>

+ 3 - 3
test/fixtures/scoreOutput.json

@@ -1,9 +1,9 @@
 {
 {
-    "globalScore": 57,
+    "globalScore": 36,
     "categories": {
     "categories": {
         "category1": {
         "category1": {
             "label": "Category 1",
             "label": "Category 1",
-            "categoryScore": 83,
+            "categoryScore": 79,
             "rules": [
             "rules": [
                 "metric1",
                 "metric1",
                 "metric2",
                 "metric2",
@@ -13,7 +13,7 @@
         },
         },
         "category2": {
         "category2": {
             "label": "Category 2",
             "label": "Category 2",
-            "categoryScore": 0,
+            "categoryScore": -55,
             "rules": [
             "rules": [
                 "metric5",
                 "metric5",
                 "metric6",
                 "metric6",

Some files were not shown because too many files changed in this diff