New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

timeliner

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

timeliner - npm Package Compare versions

Comparing version 0.7.3 to 1.0.0-0

22

lib/index.js
const Promise = require('bluebird');
const Progress = require('cli-progress');

@@ -11,3 +12,3 @@ const chromedriver = require('./chromedriver');

opts.scroll = opts.scroll || false;
if (!opts.url) {
if (!opts.url || opts.url.length === 0) {
return Promise.reject(new Error('`url` option must be provided'));

@@ -17,3 +18,20 @@ }

return Promise.using(chromedriver(), () => {
return runner(opts);
if (typeof opts.url === 'string') {
opts.url = [opts.url];
}
if (opts.progress) {
opts.progress = new Progress.Bar({ format: '[{bar}] {percentage}% | ETA: {eta_formatted}' });
opts.progress.start(opts.url.length * opts.count);
} else {
opts.progress = { increment: () => {}, stop: () => {} };
}
return Promise.map(opts.url, (url) => {
return runner(Object.assign({}, opts, { url: url }));
})
.then((result) => {
opts.progress.stop();
return result;
});
});

@@ -20,0 +38,0 @@ }

7

lib/normalise-logs.js

@@ -11,9 +11,2 @@ /**

const host = url.parse(pageurl).host;
lines = lines.map((line) => {
try {
line.message = JSON.parse(line.message);
line.timestamp = line.message.message.params.timestamp || (line.message.message.params.ts / 1e6);
} catch (e) {}
return line;
});

@@ -20,0 +13,0 @@ lines = lines.filter((l) => !isNaN(l.timestamp));

const wd = require('wd');
const Promise = require('bluebird');
const bl = require('bl');
const JSONStream = require('JSONStream');
const browser = require('./browser');
const normalise = require('./normalise-logs');
const blacklist = ['UpdateLayerTree', 'Layout', 'FunctionCall', 'UpdateLayoutTree',
'EventDispatch', 'TimerFire', 'TimerInstall', 'TimerRemove', 'ResourceSendRequest', 'ResourceReceivedData'];
function test (opts) {

@@ -36,3 +41,24 @@ return function () {

.sleep(opts.sleep)
.log('performance')
.then(() => {
return new Promise((resolve, reject) => {
session.logstream('performance')
.pipe(JSONStream.parse('value.*', (item) => {
item.message = JSON.parse(item.message);
item.name = item.message.message.params.name;
item.timestamp = item.message.message.params.timestamp || (item.message.message.params.ts / 1e6);
if (item.message.message.params && item.message.message.params.cat === '__metadata') {
return;
}
if (blacklist.indexOf(item.name) !== -1) {
return;
}
return item;
}))
.pipe(JSONStream.stringify())
.pipe(bl((err, data) => {
err ? reject(err) : resolve(JSON.parse(data.toString()));
}));
});
})
.then((logs) => {

@@ -39,0 +65,0 @@ return normalise(logs, opts.url);

@@ -57,3 +57,4 @@ const mean = require('lodash.meanby');

min: Math.min.apply(Math, timings.map(t => t[key]).filter(t => t)),
max: Math.max.apply(Math, timings.map(t => t[key]).filter(t => t))
max: Math.max.apply(Math, timings.map(t => t[key]).filter(t => t)),
raw: timings.map(t => t[key]).filter(t => t)
};

@@ -63,11 +64,13 @@ }

function basicReporter (data) {
const timings = data.map(metrics);
return data.map((d) => {
const timings = d.map(metrics);
return Object.keys(timings[0])
.reduce((list, key) => {
list[key] = result(timings, key);
return list;
}, {});
return Object.keys(timings[0])
.reduce((list, key) => {
list[key] = result(timings, key);
return list;
}, {});
});
}
module.exports = basicReporter;

@@ -32,3 +32,5 @@ const babar = require('babar');

module.exports = function (data) {
return data.map(run => chart(fps(run)));
return data.map(d => {
return d.map(run => chart(fps(run)));
});
};

@@ -0,17 +1,56 @@

'use strict';
const chalk = require('chalk');
const ttest = require('ttest');
const Table = require('cli-table');
const basic = require('./basic');
function table (data) {
function table (data, urls) {
const result = basic(data);
const table = new Table({ head: ['metric', 'mean', 'min', 'max'] });
const rows = Object.keys(result)
.map((metric) => [
metric,
result[metric].mean.toFixed(3),
result[metric].min.toFixed(3),
result[metric].max.toFixed(3)
]);
let head, rows;
if (urls.length === 1) {
head = ['metric', 'mean', 'min', 'max'];
rows = Object.keys(result[0])
.map((metric) => [
metric,
result[0][metric].mean.toFixed(3),
result[0][metric].min.toFixed(3),
result[0][metric].max.toFixed(3)
]);
} else if (urls.length === 2) {
head = ['metric'];
urls.forEach(url => head.push(url));
head.push('p < 0.05');
rows = Object.keys(result[0])
.map((metric) => {
const row = result.map((res) => {
return res[metric].mean;
});
const min = Math.min.apply(Math, row);
const max = Math.max.apply(Math, row);
const colored = row.reduce((r, m) => {
if (m === min) {
r.push(chalk.green(m.toFixed(3)));
} else if (m === max) {
r.push(chalk.red(m.toFixed(3)));
} else {
r.push(m.toFixed(3));
}
return r;
}, [metric]);
const tt = ttest(result[0][metric].raw, result[1][metric].raw, { varEqual: true });
if (!tt.valid()) {
colored.push(tt.pValue().toFixed(3) + ' ' + chalk.green('✔'));
} else {
colored.push(tt.pValue().toFixed(3) + ' ' + chalk.red('✘'));
}
return colored;
});
}
const table = new Table({ head: head });
table.push.apply(table, rows);
return table.toString();

@@ -18,0 +57,0 @@ }

@@ -6,8 +6,49 @@ const wd = require('wd');

const request = require('request');
const httpUtils = require('wd/lib/http-utils');
wd.Webdriver.prototype._stream = function (opts) {
var _this = this;
// http options init
var httpOpts = httpUtils.newHttpOpts(opts.method, this._httpConfig);
var url = httpUtils.buildJsonCallUrl(this.noAuthConfigUrl, this.sessionID, opts.relPath, opts.absPath);
// building callback
var cb = opts.cb;
if (opts.emit) {
// wrapping cb if we need to emit a message
var _cb = cb;
cb = function () {
var args = [].slice.call(arguments, 0);
_this.emit(opts.emit.event, opts.emit.message);
if (_cb) { _cb.apply(_this, args); }
};
}
// logging
httpUtils.emit(this, httpOpts.method, url, opts.data);
// writting data
var data = opts.data || {};
httpOpts.prepareToSend(url, data);
// building request
return request(httpOpts);
};
wd.Webdriver.prototype.logstream = function (logType) {
return this._stream({
method: 'POST',
relPath: '/log',
data: { type: logType }
});
};
function runner (opts) {
opts.driver = opts.driver || 'http://localhost:9515';
opts.browser = wd.remote(opts.driver, 'promiseChain');
return Promise.map(times(opts.count), page(opts), { concurrency: 1 });
const f = page(opts);
return Promise.map(times(opts.count), () => f().then((r) => { opts.progress.increment(); return r; }), { concurrency: 1 });
}
module.exports = runner;
{
"name": "timeliner",
"version": "0.7.3",
"version": "1.0.0-0",
"description": "Network Timeline Analyser",

@@ -23,6 +23,9 @@ "main": "index.js",

"bluebird": "^3.4.6",
"chalk": "^1.1.3",
"chromedriver": "^2.24.1",
"cli-progress": "^1.2.0",
"cli-table": "^0.3.1",
"lodash.meanby": "^4.10.0",
"minimist": "^1.2.0",
"ttest": "^1.1.0",
"wd": "^1.0.0"

@@ -29,0 +32,0 @@ },

@@ -26,3 +26,26 @@ # timeliner

### Side by side comparison:
You can run timeliner against two websites in parallel which will return a comparison of metrics, with an indicator of whether the difference is statistically significant (p<0.05).
```shell
$ timeliner https://facebook.com https://twitter.com
# outputs
┌──────────────────┬──────────────────────┬─────────────────────┬──────────┐
│ metric │ https://facebook.com │ https://twitter.com │ p < 0.05 │
├──────────────────┼──────────────────────┼─────────────────────┼──────────┤
│ render │ 0.835 │ 1.441 │ 0.079 ✘ │
├──────────────────┼──────────────────────┼─────────────────────┼──────────┤
│ domcontentloaded │ 0.916 │ 1.492 │ 0.080 ✘ │
├──────────────────┼──────────────────────┼─────────────────────┼──────────┤
│ load │ 0.989 │ 3.036 │ 0.118 ✘ │
└──────────────────┴──────────────────────┴─────────────────────┴──────────┘
```
*Note: you may need to increase the count option (i.e. sample size) in order to see statistical significance.*
### Scrolling performance:
```shell
# analyse scrolling performance on a long webpage

@@ -62,2 +85,6 @@ $ timeliner http://buzzfeed.com --reporter fps --sleep 5000

### `progress`
if set then a progress bar will be output to the console showing test execution progress
### `scroll`

@@ -64,0 +91,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc