From 178f2fd13520e8bab0c0696d0e4987e8db5fef1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sat, 9 Jan 2016 00:10:01 +0100 Subject: [PATCH 01/22] Add Http2 detection --- front/src/views/rule.html | 12 ++++ lib/metadata/policies.js | 29 +++++++++ lib/metadata/scoreProfileGeneric.json | 1 + lib/runner.js | 6 ++ lib/tools/isHttp2.js | 87 +++++++++++++++++++++++++++ package.json | 1 + test/core/isHttp2Test.js | 48 +++++++++++++++ 7 files changed, 184 insertions(+) create mode 100644 lib/tools/isHttp2.js create mode 100644 test/core/isHttp2Test.js diff --git a/front/src/views/rule.html b/front/src/views/rule.html index 39bb18b..7301e85 100644 --- a/front/src/views/rule.html +++ b/front/src/views/rule.html @@ -369,6 +369,18 @@ +
+

Protocols advertised by the server

+
+
+
{{protocol}}
+
+
+
none
+
+
+
+

404

Rule "{{policyName}}"" not found diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index 514318a..4721ed9 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -1044,6 +1044,35 @@ var policies = { "isAbnormalThreshold": 30, "hasOffenders": true }, + "http2": { + "label": "HTTP/2 or SPDY", + "message": "

HTTP/2 is the latest version of the HTTP protocol and is designed to optimize load speed. SPDY is deprecated but still very well supported.

The latest versions of all major browsers are now compatible. The difficulty is on the server side, where technologies are not quite ready yet.

", + "hasOffenders": true, + "scoreFn": function(data) { + if (!data.toolsResults.http2) { + return null; + } + + var isHttp2 = data.toolsResults.http2.metrics.http2; + + var result = { + value: isHttp2 ? 'Yes' : 'No', + score: isHttp2 ? 100 : 0, + bad: !isHttp2, + abnormal: false, + abnormalityScore: 0 + }; + + if (data.toolsResults.http2.offenders) { + result.offendersObj = { + count: data.toolsResults.http2.offenders.http2.length, + list: data.toolsResults.http2.offenders.http2 + }; + } + + return result; + } + }, "cachingDisabled": { "tool": "phantomas", "label": "Caching disabled", diff --git a/lib/metadata/scoreProfileGeneric.json b/lib/metadata/scoreProfileGeneric.json index 9c2f68f..a65a931 100644 --- a/lib/metadata/scoreProfileGeneric.json +++ b/lib/metadata/scoreProfileGeneric.json @@ -96,6 +96,7 @@ "serverConfig": { "label": "Server config", "policies": { + "http2": 2, "closedConnections": 2, "cachingNotSpecified": 1, "cachingDisabled": 1, diff --git a/lib/runner.js b/lib/runner.js index e5fa3c7..977355c 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -5,6 +5,7 @@ var phantomasWrapper = require('./tools/phantomas/phantomasWrapper'); var jsExecutionTransformer = require('./tools/jsExecutionTransformer'); var colorDiff = require('./tools/colorDiff'); var mediaQueriesChecker = require('./tools/mediaQueriesChecker'); +var isHttp2 = require('./tools/isHttp2'); var weightChecker = require('./tools/weightChecker/weightChecker'); var rulesChecker = require('./rulesChecker'); var scoreCalculator = require('./scoreCalculator'); @@ -41,6 +42,11 @@ var Runner = function(params) { }) + .then(function(data) { + // Check if HTTP2 + return isHttp2.check(data); + }) + .then(function(data) { // Rules checker diff --git a/lib/tools/isHttp2.js b/lib/tools/isHttp2.js new file mode 100644 index 0000000..0af9753 --- /dev/null +++ b/lib/tools/isHttp2.js @@ -0,0 +1,87 @@ +var debug = require('debug')('ylt:isHttp2'); +var url = require('url'); +var Q = require('q'); +var http2 = require('is-http2'); + +var isHttp2 = function() { + 'use strict'; + + this.check = function(data) { + debug('Starting to check for HTTP2 support...'); + + return this.checkHttp2(data) + + .then(function(result) { + + if (result.isHttp2) { + debug('HTTP/2 (or SPDY) is supported'); + + data.toolsResults.http2 = { + metrics: { + http2: true + } + }; + + } else { + debug('HTTP/2 is not supported'); + + data.toolsResults.http2 = { + metrics: { + http2: false + } + }; + } + + // Add the supported protocols as offenders + if (result.supportedProtocols) { + debug('Supported protocols: ' + result.supportedProtocols.join(' ')); + data.toolsResults.http2.offenders = { + http2: result.supportedProtocols + }; + } + + debug('End of HTTP2 support check'); + + return data; + }) + + .fail(function() { + return data; + }); + }; + + this.getParsedUrl = function(data) { + return url.parse(data.toolsResults.phantomas.url); + }; + + this.getProtocol = function(data) { + return this.getParsedUrl(data).protocol; + }; + + this.getDomain = function(data) { + return this.getParsedUrl(data).hostname; + }; + + this.checkHttp2 = function(data) { + var deferred = Q.defer(); + + var domain = this.getDomain(data); + + // To make is-http2 work, you need to have openssl in a version greater than 1.0.0 installed and available in your $path. + http2(domain, {includeSpdy: true}) + + .then(function(result) { + deferred.resolve(result); + }) + + .catch(function(error) { + debug('Error while checking HTTP2 support:'); + debug(error); + deferred.reject('Error while checking for HTTP2 support'); + }); + + return deferred.promise; + }; +}; + +module.exports = new isHttp2(); \ No newline at end of file diff --git a/package.json b/package.json index c8a75c8..35e8866 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "express": "4.13.3", "imagemin": "4.0.0", "imagemin-jpegoptim": "4.1.0", + "is-http2": "1.0.4", "jstoxml": "0.2.3", "lwip": "0.0.8", "meow": "3.6.0", diff --git a/test/core/isHttp2Test.js b/test/core/isHttp2Test.js new file mode 100644 index 0000000..1ace12e --- /dev/null +++ b/test/core/isHttp2Test.js @@ -0,0 +1,48 @@ +var should = require('chai').should(); +var isHttp2 = require('../../lib/tools/isHttp2'); + +describe('isHttp2', function() { + + it('should parse the protocol correctly', function() { + isHttp2.getProtocol({ + toolsResults: { + phantomas: { + url: 'http://www.yahoo.com' + } + } + }).should.equal('http:'); + + + isHttp2.getProtocol({ + toolsResults: { + phantomas: { + url: 'https://www.yahoo.com' + } + } + }).should.equal('https:'); + }); + + it('should parse the domain correctly', function() { + isHttp2.getDomain({ + toolsResults: { + phantomas: { + url: 'http://www.yahoo.com' + } + } + }).should.equal('www.yahoo.com'); + + + isHttp2.getDomain({ + toolsResults: { + phantomas: { + url: 'https://www.yahoo.com' + } + } + }).should.equal('www.yahoo.com'); + }); + + it('should have a function checkHttp2', function() { + isHttp2.should.have.a.property('checkHttp2').that.is.a('function'); + }); + +}); From e238370bc8aa8e3d0fd73bd816e20c9ef0d4ea2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sat, 9 Jan 2016 00:22:51 +0100 Subject: [PATCH 02/22] Release of jQuery 2.2 --- lib/metadata/policies.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index 514318a..8a074c6 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -267,7 +267,7 @@ var policies = { }, "jQueryVersion": { "label": "jQuery version", - "message": "

Current latest versions of jQuery are 1.11 (with support for old IE versions) and 2.1 (without).

Each new version of jQuery optimizes performances. Do not keep an old version of jQuery. Updating can sometimes break a few things, but it is generally quite easy to fix them up. So don't hesitate.

", + "message": "

Current latest versions of jQuery are 1.12 (with support for old IE versions) and 2.2 (without).

Each new version of jQuery optimizes performances. Do not keep an old version of jQuery. Updating can sometimes break a few things, but it is generally quite easy to fix them up. So don't hesitate.

", "hasOffenders": false, "scoreFn": function(data) { var differentVersions = data.toolsResults.phantomas.metrics.jQueryVersionsLoaded; @@ -279,27 +279,29 @@ var policies = { var value = data.toolsResults.phantomas.metrics.jQueryVersion; var score; - if (value.indexOf('1.11.') === 0 || - value.indexOf('1.12.') === 0 || - value.indexOf('2.1.') === 0 || + if (value.indexOf('1.12.') === 0 || value.indexOf('2.2.') === 0 || - value.indexOf('3.0.') === 0) { + value.indexOf('3.0.') === 0 || + value.indexOf('3.1.') === 0) { score = 100; + } else if (value.indexOf('1.11.') === 0 || + value.indexOf('2.1.') === 0) { + score = 90; } else if (value.indexOf('1.10.') === 0 || value.indexOf('2.0.') === 0) { - score = 90; - } else if (value.indexOf('1.9.') === 0) { score = 70; - } else if (value.indexOf('1.8.') === 0) { + } else if (value.indexOf('1.9.') === 0) { score = 50; - } else if (value.indexOf('1.7') === 0) { + } else if (value.indexOf('1.8.') === 0) { score = 40; - } else if (value.indexOf('1.6') === 0) { + } else if (value.indexOf('1.7') === 0) { score = 30; - } else if (value.indexOf('1.5') === 0) { + } else if (value.indexOf('1.6') === 0) { score = 20; - } else if (value.indexOf('1.4') === 0) { + } else if (value.indexOf('1.5') === 0) { score = 10; + } else if (value.indexOf('1.4') === 0) { + score = 0; } else if (value.indexOf('1.3') === 0) { score = 0; } else if (value.indexOf('1.2') === 0) { From 8bd3a1edde858ca528dfac39bd3ad79943f307b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Tue, 12 Jan 2016 00:09:35 +0100 Subject: [PATCH 03/22] Add screenshot width setting --- lib/server/controllers/apiController.js | 2 +- server_config/settings-prod.json | 1 + server_config/settings.json | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/server/controllers/apiController.js b/lib/server/controllers/apiController.js index 56d377b..a2addbf 100644 --- a/lib/server/controllers/apiController.js +++ b/lib/server/controllers/apiController.js @@ -96,7 +96,7 @@ var ApiController = function(app) { if (run.params.screenshot) { // Replace the empty promise created earlier with Q.resolve() - screenshotPromise = screenshot.toThumbnail(400) + screenshotPromise = screenshot.toThumbnail(serverSettings.screenshotWidth || 400) // Read screenshot .then(function(screenshotBuffer) { diff --git a/server_config/settings-prod.json b/server_config/settings-prod.json index cddfdae..b3d890d 100644 --- a/server_config/settings-prod.json +++ b/server_config/settings-prod.json @@ -2,6 +2,7 @@ "serverPort": 80, "phantomasEngine": "webkit", "googleAnalyticsId": "", + "screenshotWidth": 400, "authorizedKeys": { diff --git a/server_config/settings.json b/server_config/settings.json index dcd2136..6b7bc71 100644 --- a/server_config/settings.json +++ b/server_config/settings.json @@ -2,6 +2,7 @@ "serverPort": 8383, "phantomasEngine": "webkit", "googleAnalyticsId": "", + "screenshotWidth": 400, "authorizedKeys": { From 5e37cf822494527ac2df82d1d46ab92462b32ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Wed, 2 Mar 2016 22:41:18 +0100 Subject: [PATCH 04/22] Update Phantomas to v1.14 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 35e8866..e59029c 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "meow": "3.6.0", "minimize": "1.7.4", "parse-color": "1.0.0", - "phantomas": "1.13.0", + "phantomas": "1.14.0", "ps-node": "0.0.5", "q": "1.4.1", "request": "2.67.0", From 2aa9edeb8f13503cfbbc1f28bccfeb2458f6db99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sun, 20 Mar 2016 14:55:19 +0200 Subject: [PATCH 05/22] Webkit2 engine does not exist anymore in phantomas 1.14 --- lib/tools/phantomas/phantomasWrapper.js | 5 ----- package.json | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/tools/phantomas/phantomasWrapper.js b/lib/tools/phantomas/phantomasWrapper.js index 7d51542..4fc9e38 100644 --- a/lib/tools/phantomas/phantomasWrapper.js +++ b/lib/tools/phantomas/phantomasWrapper.js @@ -118,11 +118,6 @@ var PhantomasWrapper = function() { async.retry(triesNumber, function(cb) { currentTry ++; - // Fix for https://github.com/gmetais/YellowLabTools/issues/114 - if (currentTry === 2 && options.engine === 'webkit2') { - debug('Launching a second try with the old webkit v1 engine'); - options.engine = 'webkit'; - } var process = phantomas(task.url, options, function(err, json, results) { var errorCode = err ? parseInt(err.message, 10) : null; diff --git a/package.json b/package.json index e59029c..07c772a 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "meow": "3.6.0", "minimize": "1.7.4", "parse-color": "1.0.0", - "phantomas": "1.14.0", + "phantomas": "git://github.com/gmetais/phantomas.git#fix-about-blank", "ps-node": "0.0.5", "q": "1.4.1", "request": "2.67.0", From f8431849701a644e4d27e2d69ed16d2bae8aa508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sun, 20 Mar 2016 16:20:57 +0200 Subject: [PATCH 06/22] Add forgottent screenshotWidth parameter to tests --- test/fixtures/settings.json | 1 + 1 file changed, 1 insertion(+) diff --git a/test/fixtures/settings.json b/test/fixtures/settings.json index 58c89ca..a68db4c 100644 --- a/test/fixtures/settings.json +++ b/test/fixtures/settings.json @@ -2,6 +2,7 @@ "serverPort": "8387", "phantomasEngine": "webkit", "googleAnalyticsId": "", + "screenshotWidth": 400, "authorizedKeys": { "1234567890": "contact@gaelmetais.com" From 3948eeaad4ba180aa3c28b6e2ab578b13acca816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Mon, 21 Mar 2016 21:28:17 +0200 Subject: [PATCH 07/22] New advanced settings: block domains --- front/src/css/index.css | 3 +- front/src/js/services/apiService.js | 37 +++++++++++++++++-------- front/src/less/index.less | 2 +- front/src/views/dashboard.html | 7 +++++ front/src/views/index.html | 17 ++++++++---- lib/runner.js | 7 ++++- lib/server/controllers/apiController.js | 8 +++++- lib/tools/phantomas/phantomasWrapper.js | 4 ++- 8 files changed, 63 insertions(+), 22 deletions(-) diff --git a/front/src/css/index.css b/front/src/css/index.css index fa05717..8bcc1ff 100644 --- a/front/src/css/index.css +++ b/front/src/css/index.css @@ -34,7 +34,8 @@ font-size: 1em; } .settings input[type=text], -.settings input[type=password] { +.settings input[type=password], +.settings textarea { width: 100%; min-width: 4em; } diff --git a/front/src/js/services/apiService.js b/front/src/js/services/apiService.js index 0482748..95aad1e 100644 --- a/front/src/js/services/apiService.js +++ b/front/src/js/services/apiService.js @@ -14,20 +14,22 @@ apiService.factory('API', ['$location', 'Runs', 'Results', function($location, R waitForSelector: settings.waitForSelector, cookie: settings.cookie, authUser: settings.authUser, - authPass: settings.authPass + authPass: settings.authPass, + blockDomain: settings.blockDomain, + allowedDomains: settings.allowedDomains, + noExternals: settings.noExternals }; - if (settings.waitForSelector && settings.waitForSelector !== '') { - runObject.waitForSelector = settings.waitForSelector; - } - - if (settings.cookie && settings.cookie !== '') { - runObject.cookie = settings.cookie; - } - - if (settings.authUser && settings.authUser !== '' && settings.authPass && settings.authPass !== '') { - runObject.authUser = settings.authUser; - runObject.authPass = settings.authPass; + + if (settings.domainsBlackOrWhite === 'black') { + runObject.blockDomain = this.parseDomains(settings.domains); + } else if (settings.domainsBlackOrWhite === 'white') { + var allowedDomains = this.parseDomains(settings.domains); + if (allowedDomains.length > 0) { + runObject.allowDomain = allowedDomains; + } else { + runObject.noExternals = true; + } } Runs.save(runObject, function(data) { @@ -43,6 +45,17 @@ apiService.factory('API', ['$location', 'Runs', 'Results', function($location, R relaunchTest: function(result) { this.launchTest(result.params.url, result.params.options); + }, + + parseDomains: function(textareaContent) { + var lines = textareaContent.split('\n'); + + function removeEmptyLines (line) { + return line.trim() !== ''; + } + + // Remove empty lines + return lines.filter(removeEmptyLines).join(','); } }; diff --git a/front/src/less/index.less b/front/src/less/index.less index 5c665b4..bbc8b4d 100644 --- a/front/src/less/index.less +++ b/front/src/less/index.less @@ -38,7 +38,7 @@ font-size: 1em; } - input[type=text], input[type=password] { + input[type=text], input[type=password], textarea { width: 100%; min-width: 4em; } diff --git a/front/src/views/dashboard.html b/front/src/views/dashboard.html index f5dfa2c..430af91 100644 --- a/front/src/views/dashboard.html +++ b/front/src/views/dashboard.html @@ -1,6 +1,13 @@
+
+ : +
+ {{request}} +
+
+

Global score

diff --git a/front/src/views/index.html b/front/src/views/index.html index ada6eca..a72bb2a 100644 --- a/front/src/views/index.html +++ b/front/src/views/index.html @@ -61,15 +61,22 @@
- +
diff --git a/lib/runner.js b/lib/runner.js index 977355c..4c5daf2 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -66,9 +66,14 @@ var Runner = function(params) { delete data.toolsResults.phantomas.metrics.scrollExecutionTree; delete data.toolsResults.phantomas.offenders.scrollExecutionTree; + + if (data.toolsResults.phantomas.offenders.blockedRequests) { + data.blockedRequests = data.toolsResults.phantomas.offenders.blockedRequests; + } + + // Finished! deferred.resolve(data); - }) .fail(function(err) { diff --git a/lib/server/controllers/apiController.js b/lib/server/controllers/apiController.js index a2addbf..28ecd81 100644 --- a/lib/server/controllers/apiController.js +++ b/lib/server/controllers/apiController.js @@ -39,7 +39,10 @@ var ApiController = function(app) { waitForSelector: req.body.waitForSelector || null, cookie: req.body.cookie || null, authUser: req.body.authUser || null, - authPass: req.body.authPass || null + authPass: req.body.authPass || null, + blockDomain: req.body.blockDomain || null, + allowDomain: req.body.allowDomain || null, + noExternals: req.body.noExternals || false } }; @@ -77,6 +80,9 @@ var ApiController = function(app) { cookie: run.params.cookie, authUser: run.params.authUser, authPass: run.params.authPass, + blockDomain: run.params.blockDomain, + allowDomain: run.params.allowDomain, + noExternals: run.params.noExternals, phantomasEngine: serverSettings.phantomasEngine }; diff --git a/lib/tools/phantomas/phantomasWrapper.js b/lib/tools/phantomas/phantomasWrapper.js index 4fc9e38..6eeb20f 100644 --- a/lib/tools/phantomas/phantomasWrapper.js +++ b/lib/tools/phantomas/phantomasWrapper.js @@ -31,12 +31,14 @@ var PhantomasWrapper = function() { 'cookie': task.options.cookie, 'auth-user': task.options.authUser, 'auth-pass': task.options.authPass, + 'block-domain': task.options.blockDomain, + 'allow-domain': task.options.allowDomain, + 'no-externals': task.options.noExternals, // Mandatory 'reporter': 'json:pretty', 'analyze-css': true, 'skip-modules': [ - 'blockDomains', // not needed 'domHiddenContent', // overriden 'domMutations', // not compatible with webkit 'domQueries', // overriden From 113c1f056592097a9c9f5090faa494bdf5ed5a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Mon, 21 Mar 2016 23:36:07 +0200 Subject: [PATCH 08/22] Fix jQuery version unit tests --- lib/metadata/policies.js | 2 ++ test/core/customPoliciesTest.js | 25 +++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index f8fae98..bcc0f59 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -281,6 +281,8 @@ var policies = { if (value.indexOf('1.12.') === 0 || value.indexOf('2.2.') === 0 || + value.indexOf('1.13.') === 0 || + value.indexOf('2.3.') === 0 || value.indexOf('3.0.') === 0 || value.indexOf('3.1.') === 0) { score = 100; diff --git a/test/core/customPoliciesTest.js b/test/core/customPoliciesTest.js index 784bf64..2f517cd 100644 --- a/test/core/customPoliciesTest.js +++ b/test/core/customPoliciesTest.js @@ -183,18 +183,19 @@ describe('customPolicies', function() { var versions = { '1.2.9': 0, - '1.3.9': 0, - '1.4.4': 10, - '1.5.0': 20, - '1.6.3': 30, - '1.7.0': 40, - '1.8.3a': 50, - '1.9.2': 70, - '1.10.1': 90, - '2.0.0-rc1': 90, - '1.11.1': 100, - '2.1.1-beta1': 100, - '3.0.0': 100 + '1.4.4': 0, + '1.5.0': 10, + '1.6.3': 20, + '1.7.0': 30, + '1.8.3a': 40, + '1.9.2': 50, + '1.10.1': 70, + '2.0.0-rc1': 70, + '1.11.1': 90, + '2.1.1-beta1': 90, + '1.12.1': 100, + '2.3.1': 100, + '3.1.0': 100 }; for (var version in versions) { From b3804586dcf3a08f5a6b6d28c56842b5a3a36ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Wed, 23 Mar 2016 13:21:51 +0200 Subject: [PATCH 09/22] Regressing with PhantomJS 2.1, cookies don't work. Waiting for a fix. --- test/api/apiTest.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/api/apiTest.js b/test/api/apiTest.js index c13701f..10751d5 100644 --- a/test/api/apiTest.js +++ b/test/api/apiTest.js @@ -31,6 +31,7 @@ describe('api', function() { }, json: true, headers: { + 'Content-Type': 'application/json', 'X-Api-Key': 'invalid' } }, function(error, response, body) { @@ -53,6 +54,7 @@ describe('api', function() { }, json: true, headers: { + 'Content-Type': 'application/json', 'X-Api-Key': Object.keys(config.authorizedKeys)[0] } }, function(error, response, body) { @@ -76,6 +78,7 @@ describe('api', function() { }, json: true, headers: { + 'Content-Type': 'application/json', 'X-Api-Key': Object.keys(config.authorizedKeys)[0] } }, function(error, response, body) { @@ -99,12 +102,13 @@ describe('api', function() { screenshot: true, device: 'tablet', //waitForSelector: '*', - cookie: 'foo=bar', + //cookie: 'foo=bar;domain=google.com', authUser: 'joe', authPass: 'secret' }, json: true, headers: { + 'Content-Type': 'application/json', 'X-Api-Key': Object.keys(config.authorizedKeys)[0] } }, function(error, response, body) { @@ -133,6 +137,7 @@ describe('api', function() { }, json: true, headers: { + 'Content-Type': 'application/json', 'X-Api-Key': Object.keys(config.authorizedKeys)[0] } }, function(error, response, body) { @@ -172,7 +177,7 @@ describe('api', function() { // Check if settings are correctly sent and retrieved body.params.options.should.have.a.property('device').that.equals('tablet'); //body.params.options.should.have.a.property('waitForSelector').that.equals('*'); - body.params.options.should.have.a.property('cookie').that.equals('foo=bar'); + //body.params.options.should.have.a.property('cookie').that.equals('foo=bar'); body.params.options.should.have.a.property('authUser').that.equals('joe'); body.params.options.should.have.a.property('authPass').that.equals('secret'); @@ -208,6 +213,7 @@ describe('api', function() { }, json: true, headers: { + 'Content-Type': 'application/json', 'X-Api-Key': Object.keys(config.authorizedKeys)[0] } }, function(error, response, body) { @@ -232,6 +238,7 @@ describe('api', function() { url: serverUrl + '/api/runs/' + asyncRunId, json: true, headers: { + 'Content-Type': 'application/json', 'X-Api-Key': Object.keys(config.authorizedKeys)[0] } }, function(error, response, body) { From 57b30a183817b1b67553d5d3b069861e13f26d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Wed, 23 Mar 2016 13:34:23 +0200 Subject: [PATCH 10/22] Fix typo --- lib/metadata/policies.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index bcc0f59..c2f2bc0 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -929,7 +929,7 @@ var policies = { "imageOptimization": { "tool": "weightChecker", "label": "Image optimization", - "message": "

This metric mesures the number of bytes that could be saved by optimizing images.

Image optimization is generally one of the easiest way to reduce a page weight, and as a result, the page load time. Don't use Photoshop or other image editing tools, they're not very good for optimization. Use specialized tools such as Kraken.io or the excellent ImageOptim on Mac. For SVG images, you can use SVGOMG

The tools in use in YellowLabTools are not set to their maximum optimization power (JPEG quality 85), so you might be able to compress even more!

Please note that Yellow Lab Tools' engine (PhantomJS) is not compatible with image srcset (unless you use a polyfill). This can lead to incorrect page weight.

", + "message": "

This metric measures the number of bytes that could be saved by optimizing images.

Image optimization is generally one of the easiest way to reduce a page weight, and as a result, the page load time. Don't use Photoshop or other image editing tools, they're not very good for optimization. Use specialized tools such as Kraken.io or the excellent ImageOptim on Mac. For SVG images, you can use SVGOMG

The tools in use in YellowLabTools are not set to their maximum optimization power (JPEG quality 85), so you might be able to compress even more!

Please note that Yellow Lab Tools' engine (PhantomJS) is not compatible with image srcset (unless you use a polyfill). This can lead to incorrect page weight.

", "isOkThreshold": 10240, "isBadThreshold": 122880, "isAbnormalThreshold": 307200, @@ -939,7 +939,7 @@ var policies = { "gzipCompression": { "tool": "weightChecker", "label": "Gzip compression", - "message": "

Mesures the number of bytes that could be saved by compressing file transfers.

Gzip is a powerfull weight reducer and should be enabled on text-based assets in your server's configuration. Note that gzipping small files (< 1 KB) is arguable, and that some assets such as images should not be gzipped as they are already compressed. Here is a list of Content-Types that should be gzipped.

", + "message": "

Measures the number of bytes that could be saved by compressing file transfers.

Gzip is a powerfull weight reducer and should be enabled on text-based assets in your server's configuration. Note that gzipping small files (< 1 KB) is arguable, and that some assets such as images should not be gzipped as they are already compressed. Here is a list of Content-Types that should be gzipped.

", "isOkThreshold": 5125, "isBadThreshold": 81920, "isAbnormalThreshold": 153600, From 2847e02c5dd2ee92a9f5686e5ac152a6dd8a27bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Wed, 23 Mar 2016 17:11:40 +0200 Subject: [PATCH 11/22] Add an HTTPS check before checking HTTP2 --- lib/tools/isHttp2.js | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/lib/tools/isHttp2.js b/lib/tools/isHttp2.js index 0af9753..acea838 100644 --- a/lib/tools/isHttp2.js +++ b/lib/tools/isHttp2.js @@ -13,7 +13,16 @@ var isHttp2 = function() { .then(function(result) { - if (result.isHttp2) { + if (result.isHttp) { + debug('The website is not even in HTTPS'); + + data.toolsResults.http2 = { + metrics: { + http2: false + } + }; + + } else if (result.isHttp2) { debug('HTTP/2 (or SPDY) is supported'); data.toolsResults.http2 = { @@ -65,21 +74,30 @@ var isHttp2 = function() { this.checkHttp2 = function(data) { var deferred = Q.defer(); - var domain = this.getDomain(data); - - // To make is-http2 work, you need to have openssl in a version greater than 1.0.0 installed and available in your $path. - http2(domain, {includeSpdy: true}) - - .then(function(result) { - deferred.resolve(result); - }) + // Check if it's HTTPS first + if (this.getProtocol(data) === 'http:') { - .catch(function(error) { - debug('Error while checking HTTP2 support:'); - debug(error); - deferred.reject('Error while checking for HTTP2 support'); + deferred.resolve({ + isHttp: true }); + } else { + + // To make is-http2 work, you need to have openssl in a version greater than 1.0.0 installed and available in your $path. + http2(this.getDomain(data), {includeSpdy: true}) + + .then(function(result) { + deferred.resolve(result); + }) + + .catch(function(error) { + debug('Error while checking HTTP2 support:'); + debug(error); + deferred.reject('Error while checking for HTTP2 support'); + }); + + } + return deferred.promise; }; }; From a00b1a96c7bc1a9bb46e51f1dce73e4947b91d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Wed, 23 Mar 2016 17:21:26 +0200 Subject: [PATCH 12/22] Fix a bug when there is a JS redirection during the run --- lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js | 2 +- lib/tools/phantomas/custom_modules/modules/domQYLT/domQYLT.js | 2 +- lib/tools/phantomas/custom_modules/modules/eventYLT/eventYLT.js | 2 +- lib/tools/phantomas/custom_modules/modules/jQYLT/jQYLT.js | 2 +- .../modules/javaScriptBottleYLT/javaScriptBottleYLT.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js b/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js index 5bd04d3..7acac57 100644 --- a/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js +++ b/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js @@ -18,7 +18,7 @@ exports.module = function(phantomas) { responseEndTime = Date.now(); }); - phantomas.once('init', function() { + phantomas.on('init', function() { phantomas.evaluate(function(responseEndTime, deepAnalysis) { (function(phantomas) { diff --git a/lib/tools/phantomas/custom_modules/modules/domQYLT/domQYLT.js b/lib/tools/phantomas/custom_modules/modules/domQYLT/domQYLT.js index 4d71dac..be07140 100644 --- a/lib/tools/phantomas/custom_modules/modules/domQYLT/domQYLT.js +++ b/lib/tools/phantomas/custom_modules/modules/domQYLT/domQYLT.js @@ -19,7 +19,7 @@ exports.module = function(phantomas) { phantomas.setMetric('DOMqueriesAvoidable'); // @desc number of repeated uses of a duplicated query // fake native DOM functions - phantomas.once('init', function() { + phantomas.on('init', function() { phantomas.evaluate(function() { (function(phantomas) { function querySpy(type, query, fnName, context, hasNoResults) { diff --git a/lib/tools/phantomas/custom_modules/modules/eventYLT/eventYLT.js b/lib/tools/phantomas/custom_modules/modules/eventYLT/eventYLT.js index 82b678e..fd95e74 100644 --- a/lib/tools/phantomas/custom_modules/modules/eventYLT/eventYLT.js +++ b/lib/tools/phantomas/custom_modules/modules/eventYLT/eventYLT.js @@ -12,7 +12,7 @@ exports.module = function(phantomas) { phantomas.setMetric('eventsDispatched'); // @desc number of EventTarget.dispatchEvent calls phantomas.setMetric('eventsScrollBound'); // @desc number of scroll event bounds - phantomas.once('init', function() { + phantomas.on('init', function() { phantomas.evaluate(function() { (function(phantomas) { // spy calls to EventTarget.addEventListener diff --git a/lib/tools/phantomas/custom_modules/modules/jQYLT/jQYLT.js b/lib/tools/phantomas/custom_modules/modules/jQYLT/jQYLT.js index 032f21e..faf3042 100644 --- a/lib/tools/phantomas/custom_modules/modules/jQYLT/jQYLT.js +++ b/lib/tools/phantomas/custom_modules/modules/jQYLT/jQYLT.js @@ -138,7 +138,7 @@ exports.module = function(phantomas) { jQueryFunctions = jQueryFunctions.concat(jQueryTraversalFunctions); // spy calls to jQuery functions - phantomas.once('init', function() { + phantomas.on('init', function() { phantomas.evaluate(function(jQueryFunctions, jQueryTraversalFunctions) { (function(phantomas) { var oldJQuery; diff --git a/lib/tools/phantomas/custom_modules/modules/javaScriptBottleYLT/javaScriptBottleYLT.js b/lib/tools/phantomas/custom_modules/modules/javaScriptBottleYLT/javaScriptBottleYLT.js index b1b06ce..61489af 100644 --- a/lib/tools/phantomas/custom_modules/modules/javaScriptBottleYLT/javaScriptBottleYLT.js +++ b/lib/tools/phantomas/custom_modules/modules/javaScriptBottleYLT/javaScriptBottleYLT.js @@ -23,7 +23,7 @@ exports.module = function(phantomas) { phantomas.log('javaScriptBottlenecks: to spy calls to eval() run phantomas with --spy-eval option'); } - phantomas.once('init', function() { + phantomas.on('init', function() { phantomas.evaluate(function(spyEval) { (function(phantomas) { function report(msg, caller, backtrace, metric) { From 14f60d8dd3b5b61b3a9db00227160ea4d6d534aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 24 Mar 2016 09:46:08 +0200 Subject: [PATCH 13/22] Remove --js-deep-analylis & jsTimeline options, they are now on by default --- bin/cli.js | 6 --- front/src/js/services/apiService.js | 1 - lib/server/controllers/apiController.js | 10 +---- .../custom_modules/core/scopeYLT/scopeYLT.js | 38 +++++++------------ lib/tools/phantomas/phantomasWrapper.js | 1 - test/api/apiTest.js | 3 +- 6 files changed, 16 insertions(+), 43 deletions(-) diff --git a/bin/cli.js b/bin/cli.js index 54cfbe8..681e003 100644 --- a/bin/cli.js +++ b/bin/cli.js @@ -15,7 +15,6 @@ var cli = meow({ 'Options:', ' --device Use "phone" or "tablet" to simulate a mobile device (by user-agent and viewport size).', ' --screenshot Will take a screenshot and use this value as the output path. It needs to end with ".png".', - ' --js-deep-analysis When activated, the javascriptExecutionTree will contain sub-requests.', ' --wait-for-selector Once the page is loaded, Phantomas will wait until the given CSS selector matches some elements.', ' --cookie Adds a cookie on the main domain.', ' --auth-user Basic HTTP authentication username.', @@ -51,11 +50,6 @@ if (screenshot) { options.screenshot = cli.flags.screenshot; } -// Deep JS analysis option -if (cli.flags.jsDeepAnalysis === true || cli.flags.jsDeepAnalysis === 'true') { - options.jsDeepAnalysis = true; -} - // Device simulation options.device = cli.flags.device || 'desktop'; diff --git a/front/src/js/services/apiService.js b/front/src/js/services/apiService.js index 95aad1e..ba2680b 100644 --- a/front/src/js/services/apiService.js +++ b/front/src/js/services/apiService.js @@ -9,7 +9,6 @@ apiService.factory('API', ['$location', 'Runs', 'Results', function($location, R url: url, waitForResponse: false, screenshot: true, - jsTimeline: true, device: settings.device, waitForSelector: settings.waitForSelector, cookie: settings.cookie, diff --git a/lib/server/controllers/apiController.js b/lib/server/controllers/apiController.js index 28ecd81..952932d 100644 --- a/lib/server/controllers/apiController.js +++ b/lib/server/controllers/apiController.js @@ -34,7 +34,6 @@ var ApiController = function(app) { waitForResponse: req.body.waitForResponse !== false && req.body.waitForResponse !== 'false' && req.body.waitForResponse !== 0, partialResult: req.body.partialResult || null, screenshot: req.body.screenshot || false, - jsTimeline: req.body.jsTimeline || false, device: req.body.device || 'desktop', waitForSelector: req.body.waitForSelector || null, cookie: req.body.cookie || null, @@ -74,7 +73,6 @@ var ApiController = function(app) { var runOptions = { screenshot: run.params.screenshot ? screenshot.getTmpFilePath() : false, - jsDeepAnalysis: run.params.jsTimeline, device: run.params.device, waitForSelector: run.params.waitForSelector, cookie: run.params.cookie, @@ -135,13 +133,7 @@ var ApiController = function(app) { // Remove uneeded temp screenshot path delete data.params.options.screenshot; - // Empty javascriptExecutionTree if not needed - if (!run.params.jsTimeline) { - data.javascriptExecutionTree = {}; - data.scrollExecutionTree = {}; - } - - // Remove tools results if not needed + // Here we can remove tools results if not needed return resultsDatastore.saveResult(data); }) diff --git a/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js b/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js index 7acac57..aa0aaa7 100644 --- a/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js +++ b/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js @@ -19,7 +19,7 @@ exports.module = function(phantomas) { }); phantomas.on('init', function() { - phantomas.evaluate(function(responseEndTime, deepAnalysis) { + phantomas.evaluate(function(responseEndTime) { (function(phantomas) { // Overwritting phantomas spy function @@ -106,9 +106,6 @@ exports.module = function(phantomas) { var currentContext = root; var depth = 0; - if (deepAnalysis) { - phantomas.log('Entering deep Javascript analysis mode'); - } // Add a child but don't enter its context function pushContext(data) { @@ -129,9 +126,7 @@ exports.module = function(phantomas) { } } - if (depth === 0 || deepAnalysis) { - currentContext.addChild(data); - } + currentContext.addChild(data); } // Add a child to the current context and enter its context @@ -153,9 +148,7 @@ exports.module = function(phantomas) { } } - if (depth === 0 || deepAnalysis) { - currentContext = currentContext.addChild(data); - } + currentContext = currentContext.addChild(data); depth ++; } @@ -178,21 +171,18 @@ exports.module = function(phantomas) { } } - if (depth === 1 || deepAnalysis) { - - // Merge previous data with moreData (ovewrites if exists) - if (moreData) { - for (var key in moreData) { - currentContext.data[key] = moreData[key]; - } + // Merge previous data with moreData (ovewrites if exists) + if (moreData) { + for (var key in moreData) { + currentContext.data[key] = moreData[key]; } + } - var parent = currentContext.parent; - if (parent === null) { - console.error('Error: trying to close root context in ContextTree'); - } else { - currentContext = parent; - } + var parent = currentContext.parent; + if (parent === null) { + console.error('Error: trying to close root context in ContextTree'); + } else { + currentContext = parent; } depth --; @@ -255,6 +245,6 @@ exports.module = function(phantomas) { })(); })(window.__phantomas); - }, responseEndTime, phantomas.getParam('js-deep-analysis')); + }, responseEndTime); }); }; diff --git a/lib/tools/phantomas/phantomasWrapper.js b/lib/tools/phantomas/phantomasWrapper.js index 6eeb20f..ac1dfa5 100644 --- a/lib/tools/phantomas/phantomasWrapper.js +++ b/lib/tools/phantomas/phantomasWrapper.js @@ -22,7 +22,6 @@ var PhantomasWrapper = function() { // Cusomizable options 'engine': task.options.phantomasEngine || 'webkit', 'timeout': task.options.timeout || 30, - 'js-deep-analysis': task.options.jsDeepAnalysis || false, 'user-agent': (task.options.device === 'desktop') ? 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) YLT Chrome/27.0.1453.110 Safari/537.36' : null, 'tablet': (task.options.device === 'tablet'), 'phone': (task.options.device === 'phone'), diff --git a/test/api/apiTest.js b/test/api/apiTest.js index 10751d5..c47ec97 100644 --- a/test/api/apiTest.js +++ b/test/api/apiTest.js @@ -170,9 +170,8 @@ describe('api', function() { body.should.have.a.property('rules').that.is.an('object'); body.should.have.a.property('toolsResults').that.is.an('object'); - // javascriptExecutionTree should only be filled if option jsTimeline is true body.should.have.a.property('javascriptExecutionTree').that.is.an('object'); - body.javascriptExecutionTree.should.deep.equal({}); + body.javascriptExecutionTree.should.not.deep.equal({}); // Check if settings are correctly sent and retrieved body.params.options.should.have.a.property('device').that.equals('tablet'); From 299e79e8904bcd5562f09b5033d9b3f0fe1b0ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 24 Mar 2016 14:16:06 +0200 Subject: [PATCH 14/22] Fix XML report error in cli --- bin/cli.js | 5 +++-- package.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bin/cli.js b/bin/cli.js index 681e003..723e385 100644 --- a/bin/cli.js +++ b/bin/cli.js @@ -3,7 +3,7 @@ var debug = require('debug')('ylt:cli'); var meow = require('meow'); var path = require('path'); -var jstoxml = require('jstoxml'); +var EasyXml = require('easyxml'); var ylt = require('../lib/index'); @@ -80,7 +80,8 @@ if (cli.flags.reporter && cli.flags.reporter !== 'json' && cli.flags.reporter != debug('Success'); switch(cli.flags.reporter) { case 'xml': - console.log(jstoxml.toXML(data, {indent: ' '})); + var serializer = new EasyXml(); + console.log(serializer.render(data)); break; default: console.log(JSON.stringify(data, null, 2)); diff --git a/package.json b/package.json index 07c772a..77152ed 100644 --- a/package.json +++ b/package.json @@ -36,11 +36,11 @@ "cors": "2.7.1", "css-mq-parser": "0.0.3", "debug": "2.2.0", + "easyxml": "2.0.1", "express": "4.13.3", "imagemin": "4.0.0", "imagemin-jpegoptim": "4.1.0", "is-http2": "1.0.4", - "jstoxml": "0.2.3", "lwip": "0.0.8", "meow": "3.6.0", "minimize": "1.7.4", From 531d125dcc3bc816f448cd372c6abad4e6ad0a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 24 Mar 2016 15:47:50 +0200 Subject: [PATCH 15/22] Fix error 252 console output when there is a timeout while using the CLI --- lib/tools/phantomas/phantomasWrapper.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/tools/phantomas/phantomasWrapper.js b/lib/tools/phantomas/phantomasWrapper.js index ac1dfa5..520013e 100644 --- a/lib/tools/phantomas/phantomasWrapper.js +++ b/lib/tools/phantomas/phantomasWrapper.js @@ -151,6 +151,11 @@ var PhantomasWrapper = function() { } cb(errorCode, json); + + }).fail(function() { + // This function is useless, but the failing promise needs to be handled, + // otherwise the module meow writes in the console in case of a timeout (error code 252). + debug('Failing promise handled'); }); phantomasPid = process.pid; From 3f9733342332aaa67edbef16437e23b3f3bc2a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sat, 26 Mar 2016 10:25:09 +0200 Subject: [PATCH 16/22] Test different versions of Node in Travis --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3bf526f..10a882e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,8 @@ language: node_js sudo: false node_js: - - "0.12.4" + - "5.8" + - "0.12" before_install: - "npm install -g npm" - "npm install -g grunt-cli" From b7e25c4e1ccfa4a2ffe0677895284c726f8d3a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sat, 26 Mar 2016 10:25:28 +0200 Subject: [PATCH 17/22] Update Phantomas to v1.15 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77152ed..d5b43b8 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "meow": "3.6.0", "minimize": "1.7.4", "parse-color": "1.0.0", - "phantomas": "git://github.com/gmetais/phantomas.git#fix-about-blank", + "phantomas": "1.15.0", "ps-node": "0.0.5", "q": "1.4.1", "request": "2.67.0", From 74c57fc11cfee665cdf94d54e35d5087753fdfb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sat, 26 Mar 2016 10:49:17 +0200 Subject: [PATCH 18/22] Add offenders to CSSRules --- front/src/views/rule.html | 6 ++++++ lib/metadata/policies.js | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/front/src/views/rule.html b/front/src/views/rule.html index 7301e85..d6a83e8 100644 --- a/front/src/views/rule.html +++ b/front/src/views/rule.html @@ -96,6 +96,12 @@ +
+ inline CSS + + : +
+
{{offender.color1}}
{{offender.color2}}
diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index c2f2bc0..9c7b9e2 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -424,7 +424,40 @@ var policies = { "isOkThreshold": 750, "isBadThreshold": 3000, "isAbnormalThreshold": 4500, - "hasOffenders": false + "hasOffenders": true, + "offendersTransformFn": function(offenders) { + var hasInline = false; + var inlineCount = 0; + var files = []; + + offenders.forEach(function(line) { + if (line.indexOf('[inline CSS]: ') === 0) { + hasInline = true; + inlineCount += parseInt(line.substr(14)); + } else { + var parts = /^<(.*)>: (\d+)$/.exec(line); + + if (parts) { + files.push({ + file: parts[1], + rules: parseInt(parts[2], 10) + }); + } + } + }); + + if (hasInline) { + files.push({ + file: 'inline CSS', + rules: inlineCount + }); + } + + return { + count: files.length, + list: files + }; + } }, "cssComplexSelectors": { "tool": "phantomas", From aaa1ad7eaa11c170a04355983f585ffacf69342b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sat, 26 Mar 2016 11:41:51 +0200 Subject: [PATCH 19/22] Update other dependecies --- package.json | 62 ++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index d5b43b8..b246e22 100644 --- a/package.json +++ b/package.json @@ -20,52 +20,52 @@ }, "main": "./lib/index.js", "dependencies": { - "angular": "1.4.8", - "angular-animate": "1.4.8", - "angular-chart.js": "0.8.8", - "angular-local-storage": "0.2.2", - "angular-resource": "1.4.8", - "angular-route": "1.4.8", - "angular-sanitize": "1.4.8", - "async": "1.5.0", - "body-parser": "1.14.2", + "angular": "1.5.2", + "angular-animate": "1.5.2", + "angular-chart.js": "0.9.0", + "angular-local-storage": "0.2.7", + "angular-resource": "1.5.2", + "angular-route": "1.5.2", + "angular-sanitize": "1.5.2", + "async": "1.5.2", + "body-parser": "1.15.0", "chart.js": "1.0.2", - "clean-css": "3.4.8", - "color-diff": "0.1.7", - "compression": "1.6.0", + "clean-css": "3.4.10", + "color-diff": "1.0.0", + "compression": "1.6.1", "cors": "2.7.1", "css-mq-parser": "0.0.3", "debug": "2.2.0", "easyxml": "2.0.1", - "express": "4.13.3", + "express": "4.13.4", "imagemin": "4.0.0", "imagemin-jpegoptim": "4.1.0", "is-http2": "1.0.4", "lwip": "0.0.8", - "meow": "3.6.0", - "minimize": "1.7.4", + "meow": "3.7.0", + "minimize": "1.8.1", "parse-color": "1.0.0", "phantomas": "1.15.0", "ps-node": "0.0.5", "q": "1.4.1", - "request": "2.67.0", - "rimraf": "2.4.4", + "request": "2.69.0", + "rimraf": "2.5.2", "temporary": "0.0.8", "try-thread-sleep": "1.0.0", - "uglify-js": "2.6.1" + "uglify-js": "2.6.2" }, "devDependencies": { - "chai": "~3.4.0", + "chai": "~3.5.0", "grunt": "~0.4.5", "grunt-blanket": "~0.0.10", - "grunt-contrib-clean": "~0.7.0", - "grunt-contrib-concat": "~0.5.1", - "grunt-contrib-copy": "~0.8.2", - "grunt-contrib-cssmin": "~0.14.0", - "grunt-contrib-htmlmin": "~0.6.0", - "grunt-contrib-jshint": "~0.11.3", - "grunt-contrib-less": "~1.1.0", - "grunt-contrib-uglify": "~0.11.0", + "grunt-contrib-clean": "~1.0.0", + "grunt-contrib-concat": "~1.0.0", + "grunt-contrib-copy": "~1.0.0", + "grunt-contrib-cssmin": "~1.0.1", + "grunt-contrib-htmlmin": "~1.1.0", + "grunt-contrib-jshint": "~1.0.0", + "grunt-contrib-less": "~1.2.0", + "grunt-contrib-uglify": "~1.0.1", "grunt-env": "~0.4.4", "grunt-express": "~1.4.1", "grunt-filerev": "~2.3.1", @@ -74,10 +74,10 @@ "grunt-mocha-test": "~0.12.7", "grunt-replace": "~0.11.0", "grunt-usemin": "~3.1.1", - "grunt-webfont": "~1.1.0", - "matchdep": "~1.0.0", - "mocha": "~2.3.2", - "sinon": "~1.17.2", + "grunt-webfont": "~1.2.0", + "matchdep": "~1.0.1", + "mocha": "~2.4.5", + "sinon": "~1.17.3", "sinon-chai": "~2.8.0" }, "scripts": { From 8eec2549a49bb8adfec54e372ed98166dc0583b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sat, 26 Mar 2016 12:00:11 +0200 Subject: [PATCH 20/22] Trying to fix Travis build for Node 5.* --- .travis.yml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 10a882e..b29d5f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,18 @@ language: node_js sudo: false node_js: - - "5.8" - - "0.12" + - "5.8" + - "0.12" +env: + - CXX=g++-4.8 +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-4.8 before_install: - - "npm install -g npm" - - "npm install -g grunt-cli" + - "npm install -g npm" + - "npm install -g grunt-cli" install: - - "npm install" \ No newline at end of file + - "npm install" \ No newline at end of file From 76b4ca6ea506d58cc47511ed4fd2758203a34cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sat, 26 Mar 2016 17:15:47 +0200 Subject: [PATCH 21/22] Revert commented test due to cookies bug --- test/api/apiTest.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/api/apiTest.js b/test/api/apiTest.js index c47ec97..c4fb064 100644 --- a/test/api/apiTest.js +++ b/test/api/apiTest.js @@ -102,7 +102,7 @@ describe('api', function() { screenshot: true, device: 'tablet', //waitForSelector: '*', - //cookie: 'foo=bar;domain=google.com', + cookie: 'foo=bar;domain=google.com', authUser: 'joe', authPass: 'secret' }, @@ -176,7 +176,7 @@ describe('api', function() { // Check if settings are correctly sent and retrieved body.params.options.should.have.a.property('device').that.equals('tablet'); //body.params.options.should.have.a.property('waitForSelector').that.equals('*'); - //body.params.options.should.have.a.property('cookie').that.equals('foo=bar'); + body.params.options.should.have.a.property('cookie').that.equals('foo=bar;domain=google.com'); body.params.options.should.have.a.property('authUser').that.equals('joe'); body.params.options.should.have.a.property('authPass').that.equals('secret'); From eaebb3adfa90f3c3ced8279e146ebfe4dde90e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Sat, 26 Mar 2016 17:16:42 +0200 Subject: [PATCH 22/22] Update Phantomas to 1.15.1 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b246e22..4c6e11e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yellowlabtools", - "version": "1.9.3", + "version": "1.10.0", "description": "Online tool to audit a webpage for performance and front-end quality issues", "license": "GPL-2.0", "author": { @@ -45,7 +45,7 @@ "meow": "3.7.0", "minimize": "1.8.1", "parse-color": "1.0.0", - "phantomas": "1.15.0", + "phantomas": "1.15.1", "ps-node": "0.0.5", "q": "1.4.1", "request": "2.69.0",