Compare commits

...
Author SHA1 Message Date
Gaël MétaisandGitHub 773249ca4f Revert "Introduce a new "Old Image Formats" rule" 2023-08-12 04:07:03 +02:00
Gaël MétaisandGitHub 599d02ea0e Merge pull request #387 from YellowLabTools/webp-avif
Introduce a new "Old Image Formats" rule
2023-07-30 22:47:10 +02:00
Gaël Métais 675316c9b7 Wording 2023-07-26 18:02:21 +02:00
Gaël Métais c22fd8b132 Add more information to the Old Image Formats offenders 2023-07-26 17:28:53 +02:00
Gaël Métais c4b008f910 New rule that converts images to WebP and AVIF and checks the gain 2023-07-26 16:04:20 +02:00
Gaël Métais 0cde5a3607 Add Avif to content type detection 2023-07-21 10:17:18 +02:00
Gaël Métais 6180b9f86c Replace Jimp by Sharp for image processing (faster + supports webp/avif) 2023-07-20 17:38:14 +02:00
Gaël MétaisandGitHub daae7d8523 Merge pull request #386 from YellowLabTools/aws
Starting to prepare version 3.0.0
2023-07-20 16:33:05 +02:00
Gaël Métais 540e5b5ac0 Version 3.0.0 2023-07-20 16:10:46 +02:00
Gaël MétaisandGitHub 4b671001e0 Merge branch 'develop' into aws 2023-07-20 15:39:06 +02:00
Gaël Métais 1ae4bed339 Update more dependencies 2023-07-19 22:01:29 +02:00
Gaël Métais 04e734bd5a Updating some dependancies 2023-07-19 00:14:36 +02:00
Gaël Métais a0e71ef444 No support for IE10 when minifying css files 2023-07-19 00:13:44 +02:00
Gaël Métais 05d8da36d8 Fix tests 2023-07-19 00:12:51 +02:00
Gaël Métais 5cae61b896 Making ylt server work on both normal and AWS machines 2023-07-16 10:47:58 +02:00
Gaël Métais a319e84831 v2.2.0 2022-02-24 14:27:05 +01:00
Gaël MétaisandGitHub d38781400e Merge pull request #359 from EXXETA/add-storage-handling
Storage handling feature from phantomas 2.4.0
2022-02-24 14:21:32 +01:00
Kevin Kammleiter cbcc6647f2 feat(storage-handling): passthrough session and local storage 2022-01-17 13:13:07 +01:00
Gaël Métais d2a217319d Bring back the screenshot handler code 2021-05-11 00:12:25 +01:00
Gaël Métais 280b564ab3 Fix bug when the node module is called without any option 2021-05-11 00:11:47 +01:00
Gaël Métais 0e14b5bd04 Remove Lambda specific files, they will be commited into a new repository YellowLabTools/YellowLabTools-lambda-agent 2021-05-10 22:34:38 +01:00
Gaël Métais 90ded3e1cb Merge split into aws branch 2021-05-10 21:53:08 +01:00
Gaël MétaisandGitHub e795b3369d Merge pull request #344 from YellowLabTools/develop
Split YLT into two repositories
2021-05-07 16:10:53 +01:00
Gaël Métais 2f26c7db96 Fix documentation after split 2021-05-07 16:03:39 +01:00
Gaël Métais 163eef58c2 Business errors differenciated from technical errors in the Lambda runner 2021-04-11 13:14:35 +01:00
Gaël Métais 201bf75bf7 Fix unused unicode ranges metric 2021-04-04 23:43:55 +01:00
Gaël Métais ac37ebb4e2 Fix crash 2021-03-22 00:10:31 +00:00
Gaël Métais 16c3abf3f2 Remove JSHint from build steps 2021-03-22 00:06:18 +00:00
Gaël Métais d1681c3d88 Temporarily remove queue messages 2021-03-21 23:53:04 +00:00
Gaël Métais 97099e9f65 Add runId quickfix 2021-03-21 23:15:32 +00:00
Gaël Métais 4e8cb19f55 Add runId in the results 2021-03-21 23:13:56 +00:00
Gaël Métais 47eab96a67 Two version of the API: normal/lambda. Will be merged later 2021-03-20 18:24:11 +00:00
Gaël Métais ec7cba8f49 Disable browser cache in Docker 2021-03-20 18:21:28 +00:00
Gaël Métais e0d497796a Save screenshot when called with a saveFile option 2021-03-16 07:45:49 +00:00
Gaël Métais c5bc02d45d Move settings invocation to init phase 2021-03-16 07:45:10 +00:00
Gaël Métais e2b713282c Fix error Service should be called with new 2021-03-16 07:44:18 +00:00
Gaël Métais 05c883fa3e Temporarily use a fork of Phantomas for Characters Count 2021-03-15 23:22:22 +00:00
Gaël Métais e5d9680b23 Merge branch 'aws' of https://github.com/YellowLabTools/YellowLabTools into aws 2021-03-15 23:20:54 +00:00
Gaël MétaisandGitHub 4a40483348 Merge pull request #337 from ohoareau/master
feat: add Dockerfile, Makefile and lambda handler to create image for AWS Lambda
2021-03-15 23:20:35 +00:00
Gaël MétaisandGitHub 5f12d1ce0e Merge branch 'aws' into master 2021-03-15 23:19:26 +00:00
Gaël Métais 050b2303f0 Merge branch 'master' into aws 2021-03-15 23:17:37 +00:00
Olivier Hoareau 82294983b0 feat: add Dockerfile to create image for Lambda 2021-03-15 11:25:08 +01:00
Gaël Métais 8558ea29df Run YLT on AWS Lambda. TODO: should work both ways 2021-03-15 01:49:28 +00:00
Gaël Métais 9211074b32 It is now possible to save the results to an AWS S3 bucket 2021-03-14 01:49:23 +00:00
Gaël Métais 2da4371847 The screenshot is now saved in the system /tmp folder 2021-03-14 01:35:26 +00:00
Gaël Métais 791bf9fc8d Remove Yarn.lock 2021-03-13 23:58:56 +00:00
Gaël Métais e4b324d209 Clean cli.js 2021-03-13 23:57:06 +00:00
Gaël Métais 3b0bd172ba Clean results from redownload details 2021-03-13 16:08:31 +00:00
17 changed files with 234 additions and 215 deletions
+3 -1
View File
@@ -4,4 +4,6 @@ package-lock.json
tmp
coverage
package-lock.json
har.json
yarn.lock
har.json
.idea/
+1 -1
View File
@@ -70,7 +70,7 @@ By the way, it's free because I am a geek, not businessmen. In return, you can a
If your project is not accessible from outside or if you want to test your localhost, you might want to run your own instance of Yellow Lab Tools.
The classical way is to clone the project's GitHub repository and run it on Linux of MacOS. The documentation is [here](https://github.com/YellowLabTools/YellowLabTools/wiki/Install-your-private-server).
The classical way is to clone the YLT server's GitHub repository and run it on Linux or MacOS. The documentation is [here](https://github.com/YellowLabTools/YellowLabTools/wiki/Install-your-private-server).
The new recommended solution is to run Yellow Lab Tools inside a Docker virtual machine. My friend Ousama Ben Younes maintains [this ready-to-use Docker image based on Alpine](https://github.com/ousamabenyounes/docker-yellowlabtools)).
+6 -2
View File
@@ -15,7 +15,6 @@ var cli = meow({
'Options:',
' --device Simulates a device. Choose between phone (default), tablet, desktop and desktop-hd.',
' --screenshot Will take a screenshot and use this value as the output path. It needs to end with ".png".',
//' --wait-for-selector Once the page is loaded, Phantomas will wait until the given CSS selector matches some elements.',
' --proxy Sets an HTTP proxy to pass through. Syntax is "host:port".',
' --cookie Adds a cookie on the main domain.',
' --auth-user Basic HTTP authentication username.',
@@ -24,6 +23,8 @@ var cli = meow({
' --allow-domain Only allow requests to given (comma-separated) domains.',
' --no-externals Block all domains except the main one.',
' --reporter The output format: "json" or "xml". Default is "json".',
' --local-storage Ability to set a local storage, key-value pairs (e.g. "bar=foo;domain=url")',
' --session-storage Ability to set a session storage, key-value pairs (e.g. "bar=foo;domain=url")',
''
].join('\n'),
pkg: require('../package.json')
@@ -75,6 +76,10 @@ options.blockDomain = cli.flags.blockDomain || null;
options.allowDomain = cli.flags.allowDomain || null;
options.noExternals = cli.flags.noExternals || null;
// Storage injection
options.localStorage = cli.flags.localStorage;
options.sessionStorage = cli.flags.sessionStorage;
// Output format
if (cli.flags.reporter && cli.flags.reporter !== 'json' && cli.flags.reporter !== 'xml') {
console.error('Incorrect parameters: reporter has to be "json" or "xml"');
@@ -98,7 +103,6 @@ if (cli.flags.reporter && cli.flags.reporter !== 'json' && cli.flags.reporter !=
// Remove some heavy parts of the results object
delete data.toolsResults;
delete data.javascriptExecutionTree;
var xmlOutput = serializer.render(data);
+44 -10
View File
@@ -1,13 +1,13 @@
var Q = require('q');
var debug = require('debug')('ylt:index');
var Q = require('q');
var Runner = require('./runner');
var Runner = require('./runner');
var ScreenshotHandler = require('./screenshotHandler');
var packageJson = require('../package.json');
var yellowLabTools = function(url, options) {
'use strict';
var deferred = Q.defer();
if (!url) {
@@ -27,15 +27,49 @@ var yellowLabTools = function(url, options) {
var runner = new Runner(params)
.progress(deferred.notify)
.progress(deferred.notify)
.then(function(data) {
.then(function(data) {
// If a screenshot saveFunction was provided in the options
if (options && typeof options.saveScreenshotFn === 'function') {
debug('Now optimizing screenshot...');
// TODO: temporarily set all screenshot sizes to 600px, until we find a solution
ScreenshotHandler.findAndOptimizeScreenshot(data.params.options.screenshot, 600)
.then(function(screenshotBuffer) {
debug('Screenshot optimized, now saving...');
return options.saveScreenshotFn('screenshot.jpg', screenshotBuffer);
})
.then(function(response) {
debug('Screenshot saved');
debug(response);
// Remove uneeded temp screenshot path
delete data.params.options.screenshot;
})
.catch(function(err) {
// It's ok if we can't save the screenshot
debug('Screenshot could not be saved');
debug(err);
})
.finally(function() {
deferred.resolve(data);
});
} else {
deferred.resolve(data);
})
}
})
.fail(function(err) {
deferred.reject(err);
});
.catch(function(err) {
deferred.reject(err);
});
}
return deferred.promise;
+1 -1
View File
@@ -79,7 +79,7 @@ var Runner = function(params) {
});
// Fix: don't display Unicode ranges if the module is not present in Phantomas
if (!data.toolsResults.phantomas.metrics.charactersCount) {
if (!data.toolsResults.phantomas.metrics.differentCharacters) {
delete data.toolsResults.redownload.metrics.unusedUnicodeRanges;
delete data.toolsResults.redownload.offenders.unusedUnicodeRanges;
}
+108
View File
@@ -0,0 +1,108 @@
var debug = require('debug')('ylt:screenshotHandlerAgent');
var Jimp = require('jimp');
var Q = require('q');
var fs = require('fs');
var path = require('path');
var screenshotHandler = function() {
this.findAndOptimizeScreenshot = function(tmpScreenshotPath, width) {
var that = this;
debug('Starting screenshot transformation');
return this.openImage(tmpScreenshotPath)
.then(function(image) {
that.deleteTmpFile(tmpScreenshotPath);
return that.resizeImage(image, width);
})
.then(this.toBuffer);
};
this.openImage = function(imagePath) {
var deferred = Q.defer();
Jimp.read(imagePath, function(err, image){
if (err) {
debug('Could not open imagePath %s', imagePath);
debug(err);
deferred.reject(err);
} else {
debug('Image correctly open');
deferred.resolve(image);
}
});
return deferred.promise;
};
this.resizeImage = function(image, newWidth) {
var deferred = Q.defer();
var currentWidth = image.bitmap.width;
if (currentWidth > 0) {
var ratio = newWidth / currentWidth;
image.scale(ratio, function(err, image){
if (err) {
debug('Could not resize image');
debug(err);
deferred.reject(err);
} else {
debug('Image correctly resized');
deferred.resolve(image);
}
});
} else {
deferred.reject('Could not resize an empty image');
}
return deferred.promise;
};
this.toBuffer = function(image) {
var deferred = Q.defer();
image.quality(85).getBuffer(Jimp.MIME_JPEG, function(err, buffer){
if (err) {
debug('Could not save image to buffer');
debug(err);
deferred.reject(err);
} else {
debug('Image correctly transformed to buffer');
deferred.resolve(buffer);
}
});
return deferred.promise;
};
this.deleteTmpFile = function(tmpFilePath) {
var deferred = Q.defer();
fs.unlink(tmpFilePath, function (err) {
if (err) {
debug('Screenshot temporary file not found, could not be deleted. But it is not a problem.');
} else {
debug('Screenshot temporary file deleted.');
}
deferred.resolve();
});
return deferred.promise;
};
};
module.exports = new screenshotHandler();
+2 -1
View File
@@ -1,4 +1,3 @@
var async = require('async');
var Q = require('q');
var path = require('path');
var debug = require('debug')('ylt:phantomaswrapper');
@@ -43,6 +42,8 @@ var PhantomasWrapper = function() {
'block-domain': task.options.blockDomain,
'allow-domain': task.options.allowDomain,
'no-externals': task.options.noExternals,
'local-storage': task.options.localStorage,
'session-storage': task.options.sessionStorage,
// Mandatory
'analyze-css': true,
+1 -1
View File
@@ -162,7 +162,7 @@ var FileMinifier = function() {
var deferred = Q.defer();
try {
var result = new CleanCSS({compatibility: 'ie8'}).minify(body);
var result = new CleanCSS().minify(body);
deferred.resolve(result.styles);
} catch(err) {
deferred.reject(err);
+4 -1
View File
@@ -204,7 +204,10 @@ var ImageOptimizer = function() {
} else if (type === 'png' && !lossy) {
engine = imageminOptipng({optimizationLevel: OPTIPNG_COMPRESSION_LEVEL});
} else if (type === 'svg' && !lossy) {
engine = imageminSvgo({ plugins: [ { removeUselessDefs: false } ] });
engine = imageminSvgo({plugins: [{
name: 'preset-default',
params: {overrides: {removeUselessDefs: false}}
}]});
} else {
deferred.reject('No optimization engine found for imagemin');
}
+11 -3
View File
@@ -63,10 +63,9 @@ var Redownload = function() {
}
}
// Prevent a bug with the font analyzer on empty pages
var differentCharacters = '';
if (data.toolsResults.phantomas.offenders.charactersCount && data.toolsResults.phantomas.offenders.charactersCount.length > 0) {
differentCharacters = data.toolsResults.phantomas.offenders.charactersCount[0];
if (data.toolsResults.phantomas.offenders.differentCharacters && data.toolsResults.phantomas.offenders.differentCharacters.length > 0) {
differentCharacters = data.toolsResults.phantomas.offenders.differentCharacters[0];
}
// Transform every request into a download function with a callback when done
@@ -195,6 +194,8 @@ var Redownload = function() {
offenders: offenders
};
cleanResults(results);
deferred.resolve(data);
}
});
@@ -1010,6 +1011,13 @@ var Redownload = function() {
}
}
// Clean all the pollution this module added to the results
function cleanResults(requests) {
requests.forEach(function(req) {
delete req.weightCheck;
});
}
return {
recheckAllFiles: recheckAllFiles,
listRequestWeight: listRequestWeight,
+18 -17
View File
@@ -1,6 +1,6 @@
{
"name": "yellowlabtools",
"version": "2.1.0",
"version": "3.0.0",
"description": "A tool that audits a webpage for performance and front-end quality issues",
"license": "GPL-2.0",
"author": {
@@ -16,24 +16,24 @@
"yellowlabtools": "./bin/cli.js"
},
"engines": {
"node": ">= 12.0"
"node": ">= 16.0"
},
"main": "./lib/index.js",
"dependencies": {
"async": "2.6.1",
"clean-css": "4.2.1",
"color-diff": "1.1.0",
"color-diff": "1.4.0",
"css-mq-parser": "0.0.3",
"debug": "4.1.1",
"debug": "4.3.4",
"easyxml": "2.0.1",
"fontkit": "1.7.8",
"fontkit": "2.0.2",
"html-minifier": "4.0.0",
"image-size": "0.7.1",
"image-size": "1.0.2",
"imagemin": "7.0.1",
"imagemin-jpegoptim": "7.0.0",
"imagemin-jpegtran": "7.0.0",
"imagemin-optipng": "8.0.0",
"imagemin-svgo": "8.0.0",
"imagemin-svgo": "9.0.0",
"is-eot": "1.0.0",
"is-gif": "3.0.0",
"is-jpg": "2.0.0",
@@ -45,24 +45,25 @@
"is-webp": "1.0.1",
"is-woff": "1.0.3",
"is-woff2": "1.0.0",
"md5": "2.2.1",
"jimp": "0.22.8",
"md5": "2.3.0",
"meow": "5.0.0",
"parse-color": "1.0.0",
"phantomas": "2.2.0",
"phantomas": "2.8.0",
"q": "1.5.1",
"request": "2.88.0",
"ttf2woff2": "4.0.1",
"uglify-js": "3.4.9",
"request": "2.88.2",
"ttf2woff2": "5.0.0",
"uglify-js": "3.17.4",
"woff-tools": "0.1.0"
},
"devDependencies": {
"chai": "~4.2.0",
"mocha": "~5.2.0",
"sinon": "~7.2.3",
"sinon-chai": "~3.3.0"
"chai": "~4.3.7",
"mocha": "~10.2.0",
"sinon": "~15.2.0",
"sinon-chai": "3.7.0"
},
"scripts": {
"test": "todo"
"test": "mocha './test/core/**.js'"
},
"keywords": [
"performance",
+2 -2
View File
@@ -49,7 +49,7 @@ describe('colorDiff', function() {
{url:'file.css', value: {message: '#5bc0de (2 times)'}},
{url:'file.css', value: {message: 'rgba(0,0,0,0.075) (100 times)'}},
{url:'file.css', value: {message: 'rgb(91,192,222) (1000 times)'}},
{url:'file.css', value: {message: 'rgba(0,0,2,1) (1 times)'}},
{url:'file.css', value: {message: 'rgba(0,0,1,1) (1 times)'}},
{url:'file.css', value: {message: 'rgba(99,99,99,1) (1 times)'}},
{url:'file.css', value: {message: 'rgba(100,100,100,1) (1 times)'}}
];
@@ -73,7 +73,7 @@ describe('colorDiff', function() {
newData.toolsResults.colorDiff.offenders.should.have.a.property('similarColors').that.deep.equals([
{
color1: '#000',
color2: 'rgba(0,0,2,1)',
color2: 'rgba(0,0,1,1)',
isDark: true
},
{
+10 -114
View File
@@ -76,114 +76,6 @@ describe('customPolicies', function() {
});
it('should transform DOMqueriesAvoidable offenders', function() {
results = rulesChecker.check({
"toolsResults": {
"phantomas": {
"metrics": {
"DOMqueriesAvoidable": 2
},
"offenders": {
"DOMqueriesDuplicated": [
"id \"#j2t-top-cart\" with getElementById (in context #document): 4 queries",
"class \".listingResult\" with getElementsByClassName (in context body > div#Global > div#Listing): 4 queries"
]
}
}
}
}, policies);
results.should.have.a.property('DOMqueriesAvoidable');
results.DOMqueriesAvoidable.should.have.a.property('offendersObj').that.deep.equals({
"count": 2,
"list": [
{
"query": "#j2t-top-cart",
"context": {
"type": "document"
},
"fn": "getElementById ",
"count": 4
},
{
"query": ".listingResult",
"context": {
"type": "domElement",
"element": "div#Listing",
"tree": {
"body": {
"div#Global": {
"div#Listing": 1
}
}
}
},
"fn": "getElementsByClassName ",
"count": 4
}
]
});
});
it('should transform jsErrors offenders', function() {
results = rulesChecker.check({
"toolsResults": {
"phantomas": {
"metrics": {
"jsErrors": 2
},
"offenders": {
"jsErrors": [
"TypeError: 'undefined' is not a function (evaluating 'this.successfullyCollected.bind(this)') - http://asset.easydmp.net/js/collect.js:1160 / callCollecte http://asset.easydmp.net/js/collect.js:1203 / callbackUpdateParams http://asset.easydmp.net/js/collect.js:1135 / http://asset.easydmp.net/js/collect.js:1191",
"TypeError: 'undefined' is not an object (evaluating 'd.readyState') - http://me.hunkal.com/p/:3"
]
}
}
}
}, policies);
results.should.have.a.property('jsErrors');
results.jsErrors.should.have.a.property('offendersObj').that.deep.equals({
"count": 2,
"list": [
{
"error": "TypeError: 'undefined' is not a function (evaluating 'this.successfullyCollected.bind(this)')",
"backtrace": [
{
"file": "http://asset.easydmp.net/js/collect.js",
"line": 1160
},
{
"file": "http://asset.easydmp.net/js/collect.js",
"line": 1203,
"functionName": "callCollecte"
},
{
"file": "http://asset.easydmp.net/js/collect.js",
"line": 1135,
"functionName": "callbackUpdateParams"
},
{
"file": "http://asset.easydmp.net/js/collect.js",
"line": 1191
}
]
},
{
"error": "TypeError: 'undefined' is not an object (evaluating 'd.readyState')",
"backtrace": [
{
"file": "http://me.hunkal.com/p/",
"line": 3
}
]
}
]
});
});
it('should grade correctly jQuery versions', function() {
var versions = {
@@ -208,7 +100,8 @@ describe('customPolicies', function() {
"phantomas": {
"metrics": {
"jQueryVersion": version
}
},
"offenders": {}
}
}
}, policies);
@@ -222,11 +115,12 @@ describe('customPolicies', function() {
"phantomas": {
"metrics": {
"jQueryVersion": "wooot"
}
},
"offenders": {}
}
}
}, policies);
results.should.deep.equals({});
results.should.not.have.a.property('jQueryVersion');
// If jQueryVersionsLoaded is 0
@@ -236,7 +130,8 @@ describe('customPolicies', function() {
"metrics": {
"jQueryVersion": "1.6.0",
"jQueryVersionsLoaded": 0
}
},
"offenders": {}
}
}
}, policies);
@@ -252,14 +147,15 @@ describe('customPolicies', function() {
"metrics": {
"jQueryVersion": "1.6.0",
"jQueryVersionsLoaded": 2
}
},
"offenders": {}
}
}
}, policies);
results.should.not.have.a.property('jQueryVersion');
results.should.have.a.property('jQueryVersionsLoaded');
results.jQueryVersionsLoaded.should.have.a.property('score').that.equals(0);
results.jQueryVersionsLoaded.should.have.a.property('abnormal').that.equals(true);
results.jQueryVersionsLoaded.should.have.a.property('abnormal').that.equals(false);
});
+17 -9
View File
@@ -12,13 +12,13 @@ chai.use(sinonChai);
describe('index.js', function() {
it('should return a promise', function() {
var promise = ylt();
/*var promise = ylt();
promise.should.have.property('then').that.is.a('function');
promise.should.have.property('fail').that.is.a('function');
promise.should.have.property('fail').that.is.a('function');*/
});
it('should fail an undefined url', function(done) {
it('should fail with an undefined url', function(done) {
ylt().fail(function(err) {
err.should.be.a('string').that.equals('URL missing');
done();
@@ -50,7 +50,7 @@ describe('index.js', function() {
data.toolsResults.phantomas.should.be.an('object');
data.toolsResults.phantomas.should.have.a.property('url').that.equals(url);
data.toolsResults.phantomas.should.have.a.property('metrics').that.is.an('object');
data.toolsResults.phantomas.metrics.should.have.a.property('requests').that.equals(1);
data.toolsResults.phantomas.metrics.should.have.a.property('requests').that.equals(2);
data.toolsResults.phantomas.should.have.a.property('offenders').that.is.an('object');
data.toolsResults.phantomas.offenders.should.have.a.property('DOMelementMaxDepth');
data.toolsResults.phantomas.offenders.DOMelementMaxDepth.should.have.length(2);
@@ -66,13 +66,14 @@ describe('index.js', function() {
"tool": "phantomas",
"label": "DOM max depth",
"message": "<p>A deep DOM makes the CSS matching with DOM elements difficult.</p><p>It also slows down JavaScript modifications to the DOM because changing the dimensions of an element makes the browser re-calculate the dimensions of it's parents. Same thing for JavaScript events, that bubble up to the document root.</p>",
"isOkThreshold": 12,
"isBadThreshold": 22,
"isAbnormalThreshold": 30,
"isOkThreshold": 15,
"isBadThreshold": 25,
"isAbnormalThreshold": 32,
"hasOffenders": true
},
"value": 1,
"bad": false,
"globalScoreIfFixed": 98,
"abnormal": false,
"score": 100,
"abnormalityScore": 0,
@@ -90,10 +91,10 @@ describe('index.js', function() {
/*jshint expr: true*/
console.log.should.not.have.been.called;
console.log.restore();
//console.log.restore();
done();
}).fail(function(err) {
console.log.restore();
//console.log.restore();
done(err);
});
});
@@ -105,6 +106,7 @@ describe('index.js', function() {
ylt(url)
.then(function(data) {
console.log(data.toolsResults.phantomas.offenders.jsErrors);
data.toolsResults.phantomas.metrics.should.have.a.property('jsErrors').that.equals(0);
done();
}).fail(function(err) {
@@ -119,6 +121,10 @@ describe('index.js', function() {
var url = 'http://localhost:8388/simple-page.html';
var screenshotPath = path.join(__dirname, '../../.tmp/indexTestScreenshot.png');
if (!fs.existsSync(path.join(__dirname, '../../.tmp'))){
fs.mkdirSync(path.join(__dirname, '../../.tmp'));
}
ylt(url, {screenshot: screenshotPath})
.then(function(data) {
@@ -130,6 +136,8 @@ describe('index.js', function() {
done();
}).fail(function(err) {
done(err);
}).finally(function() {
});
});
-48
View File
@@ -1,48 +0,0 @@
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');
});
});
+5 -4
View File
@@ -89,9 +89,9 @@ describe('redownload', function() {
data.toolsResults.redownload.offenders.should.have.a.property('imagesTooLarge');
data.toolsResults.redownload.offenders.imagesTooLarge.length.should.equal(0);
data.toolsResults.redownload.offenders.should.have.a.property('gzipCompression');
data.toolsResults.redownload.offenders.gzipCompression.totalGain.should.be.above(0);
data.toolsResults.redownload.offenders.gzipCompression.files.length.should.equal(5);
data.toolsResults.redownload.offenders.should.have.a.property('compression');
data.toolsResults.redownload.offenders.compression.totalGain.should.be.above(0);
data.toolsResults.redownload.offenders.compression.files.length.should.equal(5);
data.toolsResults.redownload.offenders.should.have.a.property('fileMinification');
data.toolsResults.redownload.offenders.fileMinification.totalGain.should.be.above(0);
@@ -224,7 +224,8 @@ describe('redownload', function() {
},
status: 302,
isHTML: true,
contentLength: 999
contentLength: 999,
notFound: true
};
redownload.redownloadEntry(entry)
+1
View File
@@ -9,6 +9,7 @@
document.getElementById(undefined);
document.getElementsByClassName(undefined);
document.getElementsByTagName(undefined);
document.querySelector(undefined);
} catch(err) {
console.log('Error found: ' + err);