Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

webpagetest

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webpagetest - npm Package Compare versions

Comparing version 0.2.0 to 0.2.1

csi.js

29

lib/helper.js
/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License
*/
var xml2js = require('xml2js'),
url = require('url'),
os = require('os');
var xml2js = require('xml2js'),
url = require('url'),
os = require('os'),
csv = require('csv'),
entities = require('entities');

@@ -50,3 +53,2 @@ var parser = new xml2js.Parser({explicitArray: false, mergeAttrs: true});

function xmlToObj(xml, callback) {
parser.parseString(xml, function (err, obj) {

@@ -102,2 +104,18 @@ if (err) {

function csvParser(data, callback) {
csv()
.from(data.toString(), { columns: true })
.transform(function(row, index) {
var key, value;
for (key in row) {
value = row[key].replace(/<b>|<\/b>/g, '');
row[key] = entities.decode(value, 2);
}
return row;
})
.on('error', callback.bind(this))
.to.array(callback.bind(this, undefined));
}
csvParser.async = true;
// Net log has a buggy end of file, attempt to fix

@@ -228,2 +246,3 @@ function netLogParser(data) {

tsvToObj: svToObj.bind(null, '\t'),
csvParser: csvParser,
netLogParser: netLogParser,

@@ -230,0 +249,0 @@ scriptToString: scriptToString,

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -329,3 +330,3 @@ */

'cmdline': {
name: 'commnadLine',
name: 'commandLine',
api: 'cmdline',

@@ -341,2 +342,8 @@ param: 'switches',

},
'continuous': {
name: 'continuousVideoCapture',
api: 'continuousVideo',
bool: true,
info: 'capture video continuously (unstable/experimental, may cause tests to fail)'
},
'poll': {

@@ -544,2 +551,12 @@ name: 'pollResults',

}
},
'video': {
'end': {
name: 'comparisonEndPoint',
key: 'e',
api: 'end',
param: 'end_point',
info: 'frame comparison end point: [visual]=visually complete | all=last change | doc=document complete | full=fully loaded',
valid: /^(?:visual|all|doc|full)$/
}
}

@@ -630,2 +647,14 @@ };

},
'history': {
name: 'getHistory',
param: 'days',
optional: true,
info: 'get history of previously run tests'
},
'googlecsi': {
name: 'getGoogleCsiData',
param: 'id',
options: [options.run],
info: 'get Google CSI data (Client Side Instrumentation)'
},
'waterfall': {

@@ -643,2 +672,13 @@ name: 'getWaterfallImage',

},
'video': {
name: 'createVideo',
param: 'tests',
options: [options.video],
info: 'create a video from <tests> (comma separated test ids)'
},
'player': {
name: 'getEmbedVideoPlayer',
param: 'id',
info: 'get a html5 player for a video <id>'
},
'listen': {

@@ -645,0 +685,0 @@ name: 'listen',

3

lib/server.js
/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -5,0 +6,0 @@ */

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -5,0 +6,0 @@ */

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -31,3 +32,7 @@ */

thumbnail: 'thumbnail.php',
cancel: 'cancelTest.php'
cancel: 'cancelTest.php',
history: 'testlog.php',
videoCreation: 'video/create.php',
videoView: 'video/view.php',
googleCsi: 'google/google_csi.php'
};

@@ -43,2 +48,3 @@

testInfo: 'testinfo.json',
history: 'history.csv',
waterfall: 'waterfall.png',

@@ -120,2 +126,14 @@ screenshot: 'screen.jpg',

// execute callback properly normalizing optional args
function callbackYield(callback, err, data, options) {
if (typeof callback === 'function') {
callback.apply(callback, [err, data].concat(options.args));
}
}
// helper for async parser callback
function asyncParserCallback(options, err, data) {
callbackYield(this, err, data, options);
}
// WPT API call wrapper

@@ -143,3 +161,3 @@ function api(pathname, callback, query, options) {

if (typeof callback === 'function') {
callback.apply(this,
callback.apply(callback,
[undefined, helper.dryRun(config, pathname)]

@@ -156,3 +174,9 @@ );

if (options.parser) {
data = options.parser(data);
// async parser
if (options.parser.async) {
return options.parser(data,
asyncParserCallback.bind(callback, options));
} else {
data = options.parser(data);
}
} else {

@@ -164,8 +188,4 @@ if (!data) {

} else if (info.type === 'text/xml') {
helper.xmlToObj(data, function(err, obj) {
if (typeof callback === 'function') {
callback.apply(this, [err, obj].concat(options.args));
}
});
return;
return helper.xmlToObj(data,
asyncParserCallback.bind(callback, options));
} else if (info.type === 'text/html') {

@@ -180,6 +200,4 @@ data = {result: (reHTMLOutput.exec(data) || [])[1]};

if (typeof callback === 'function') {
callback.apply(this, [err, data].concat(options.args));
}
}, options.encoding);
callbackYield(callback, err, data, options);
}.bind(this), options.encoding);

@@ -193,3 +211,3 @@ }

// Set the appropriate filename to be requested
function setFilename(input, options) {
function setFilename(input, options, doNotDefault) {
var run, cached;

@@ -199,5 +217,13 @@

run = parseInt(options.run || options.r, 10) || 1;
// set run and cached with or without defaults
run = parseInt(options.run || options.r, 10) ||
(doNotDefault ? undefined : 1);
cached = (options.repeatView || options.cached || options.c) ?
filenames.cached : '';
// when falsy, check set default accordingly
if (doNotDefault && !cached) {
cached = ['repeatView', 'cached', 'c'].some(function(key) {
return key in options;
}) ? '' : undefined;
}

@@ -207,4 +233,8 @@ if (typeof input === 'string') {

} else {
input.run = run;
input.cached = cached ? 1 : 0;
if (run !== undefined) {
input.run = run;
}
if (cached !== undefined) {
input.cached = cached ? 1 : 0;
}
return input;

@@ -522,2 +552,28 @@ }

function getHistory(days, options, callback) {
var query;
callback = callback || options;
options = options === callback ? {} : options;
options.parser = options.parser || helper.csvParser;
query = {
all: 'on',
f: 'csv',
days: days ? parseInt(days, 10) : 1
};
return api.call(this, paths.history, callback, query, options);
}
function getGoogleCsiData(id, options, callback) {
var query;
callback = callback || options;
options = options === callback ? {} : options;
options.parser = options.parser || helper.csvParser;
query = setFilename({test: id}, options, true);
return api.call(this, paths.googleCsi, callback, query, options);
}
function getWaterfallImage(id, options, callback) {

@@ -591,2 +647,31 @@ var query,

function getEmbedVideoPlayer(id, options, callback) {
var params = {
embed: 1,
id: id
};
options.args = options.args || {
type: 'text/html',
encoding: options.dataURI ? 'utf8' : options.encoding
};
options.parser = function (data) {
return data.toString();
};
api.call(this, paths.videoView, callback, params, options);
}
function createVideo(tests, options, callback) {
//prefer the json format because the xml format is buggy with wpt 2.11
var params = {
tests: tests,
f: 'json',
end: options.comparisonEndPoint || 'visual'
};
api.call(this, paths.videoCreation, callback, params, options);
}
// WPT constructor

@@ -633,4 +718,8 @@ function WebPageTest(server, key) {

getTestInfo: getTestInfo,
getHistory: getHistory,
getWaterfallImage: getWaterfallImage,
getScreenshotImage: getScreenshotImage,
getGoogleCsiData: getGoogleCsiData,
getEmbedVideoPlayer: getEmbedVideoPlayer,
createVideo: createVideo,
scriptToString: WebPageTest.scriptToString,

@@ -654,2 +743,6 @@ listen: listen,

testinfo: getTestInfo,
history: getHistory,
googlecsi: getGoogleCsiData,
player: getEmbedVideoPlayer,
video: createVideo,
waterfall: getWaterfallImage,

@@ -656,0 +749,0 @@ screenshot: getScreenshotImage

{
"name": "webpagetest",
"version": "0.2.0",
"version": "0.2.1",
"description": "WebPageTest API wrapper for NodeJS",

@@ -36,9 +36,11 @@ "author": "Marcel Duran <github@marcelduran.com> (http://github.com/marcelduran)",

"dependencies": {
"commander": "~2.0.0",
"mocha": "~1.13.0",
"xml2js": "~0.2.8"
"commander": "~2.1.0",
"mocha": "~1.17.0",
"xml2js": "~0.4.1",
"csv": "~0.3.6",
"entities": "~0.3.0"
},
"devDependencies": {
"nock": "~0.22.1"
"nock": "~0.27.1"
}
}

@@ -54,4 +54,8 @@ ## WebPageTest API Wrapper for NodeJS [![Build Status](https://secure.travis-ci.org/marcelduran/webpagetest-api.png?branch=master)](http://travis-ci.org/marcelduran/webpagetest-api) [![Dependencies Status](https://david-dm.org/marcelduran/webpagetest-api.png)](https://david-dm.org/marcelduran/webpagetest-api)

* **testinfo** _\<id\>_: get test request info/details
* **history** _[days]_: get history of previously run tests
* **googlecsi** _[options] \<id\>_: get Google CSI data (Client Side Instrumentation)
* **waterfall** _[options] \<id\>_: get the waterfall PNG image
* **screenshot** _[options] \<id\>_: get the fully loaded page screenshot in JPG format (PNG if in full resolution)
* **video** _[options] \<tests\>_: create a video from _\<tests\>_ (comma separated test ids)
* **player _\<id\>_: get a html5 player for a video _\<id\>_
* **listen** _[port]_: start webpagetest-api server on port _[7791_]

@@ -133,3 +137,3 @@ * **batch** _\<file\>_: run commands in batch, i.e. one command per line from _\<file\>_ in parallel

#### Run (works for **pagespeed**, **utilization**, **request**, **timeline**, **netlog**, **console**, **waterfall** and **screenshot** commands)
#### Run (works for **pagespeed**, **utilization**, **request**, **timeline**, **netlog**, **console**, **googlecsi**, **waterfall** and **screenshot** commands)
* **-r, --run** _\<number\>_: which run number on a multiple runs test [1]

@@ -158,2 +162,5 @@ * **-c, --cached**: get the Repeat View (cached view) instead of default First View (primed cache)

#### Video (works for **video** command only)
* **-e, --end** _\<end_point\>_: frame comparison end point: [visual]=visually complete | all=last change | doc=document complete | full=fully loaded
### Examples

@@ -321,4 +328,8 @@ #### 1. Get available locations

* `getTestInfo(id, options, callback)`
* `getHistory(days, options, callback)`
* `getGoogleCsiData(id, options, callback)`
* `getWaterfallImage(id, options, callback)`
* `getScreenshotImage(id, options, callback)`
* `createVideo(tests, options, callback)`
* `getEmbedVideoPlayer(id, options, callback)`
* `listen(port, callback)`

@@ -434,3 +445,3 @@ * `scriptToString(script)`

#### Run (works for `getPageSpeedData`, `getUtilizationData`, `getRequestData`, `getTimelineData`, `getNetLogData`, `getConsoleLogData`, `getWaterfallImage` and `getScreenshotImage` methods)
#### Run (works for `getPageSpeedData`, `getUtilizationData`, `getRequestData`, `getTimelineData`, `getNetLogData`, `getConsoleLogData`, `getGoogleCsiData`, `getWaterfallImage` and `getScreenshotImage` methods)
* **run**: _Number_, the test run number for multiple runs tests (default: 1, first test)

@@ -459,2 +470,5 @@ * **repeatView**: _Boolean_, if `true` returns the repeat view (cached) data

#### Video (works for `createVideo` method only)
* **comparisonEndPoint** _String_: frame comparison end point: [visual]=visually complete | all=last change | doc=document complete | full=fully loaded
### Examples

@@ -618,2 +632,3 @@

* 0.2.1: Added history, video, player, googleCsi commands and continuous option
* 0.2.0: Replaced jsonml by xml2js dependency

@@ -641,5 +656,10 @@ * 0.1.3: Test results extra data (breakdown, domains, requests, pagespeed)

Copyright 2013 Twitter, Inc.
Copyright 2013 Marcel Duran and other contributors
Copyright 2013 Twitter Inc.
Copyright 2014 Google Inc.
Copyright 2014 Marcel Duran and other contributors
Licensed under the [MIT License](http://github.com/marcelduran/webpagetest-api/raw/master/LICENSE)
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/marcelduran/webpagetest-api/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -234,2 +235,11 @@ */

it('gets a history input returns the API url', function(done) {
exec(mock('history 2'), function(err, data) {
if (err) return done(err);
data = JSON.parse(data);
assert.equal(data.url, wptServer + 'testlog.php?all=on&f=csv&days=2');
done();
});
});
it('gets a waterfall image input returns the API url', function(done) {

@@ -293,3 +303,3 @@ exec(mock('waterfall 120816_V2_2'), function(err, data) {

'pagespeed', 'utilization', 'request', 'timeline', 'netlog', 'console',
'testinfo', 'waterfall', 'screenshot', 'listen'
'testinfo', 'history', 'waterfall', 'screenshot', 'listen', 'video'
].forEach(function eachCmd(command) {

@@ -296,0 +306,0 @@ it('gets a ' + command + ' help input and returns the help text', function(done) {

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -238,2 +239,10 @@ */

it('gets history request', function(done) {
wpt.getHistory(2, {dryRun: true}, function (err, data) {
if (err) return done(err);
assert.equal(data.url, wptServer + 'testlog.php?all=on&f=csv&days=2');
done();
});
});
it('gets a waterfall image request', function(done) {

@@ -360,3 +369,47 @@ wpt.getWaterfallImage('120816_V2_2', {dryRun: true}, function (err, data) {

it('create a video', function (done) {
wpt.createVideo('130416_YS_KD4-r:3-c:1,130416_W6_KEE-r:8-c:1', {dryRun: true}, function (err, data) {
if (err) throw err;
assert.equal(data.url, wptServer + 'video/create.php?tests=130416_YS_KD4-r%3A3-c%3A1%2C130416_W6_KEE-r%3A8-c%3A1&f=json&end=visual');
done();
});
});
it('create a video with document complete comparison end point', function (done) {
wpt.createVideo('130416_YS_KD4-r:3-c:1,130416_W6_KEE-r:8-c:1', {dryRun: true, comparisonEndPoint: 'doc'}, function (err, data) {
if (err) throw err;
assert.equal(data.url, wptServer + 'video/create.php?tests=130416_YS_KD4-r%3A3-c%3A1%2C130416_W6_KEE-r%3A8-c%3A1&f=json&end=doc');
done();
});
});
it('get the url of an embedded video', function (done) {
wpt.getEmbedVideoPlayer('130416_36ed6e37013655a14b2b857cdccec99db72adcaa', {dryRun: true}, function (err, data) {
if (err) throw err;
assert.equal(data.url, wptServer + 'video/view.php?embed=1&id=130416_36ed6e37013655a14b2b857cdccec99db72adcaa');
done();
});
});
it('get google csi', function(done) {
wpt.getGoogleCsiData('140101_AB_12', {dryRun: true}, function(err, data) {
if (err) throw err;
assert.equal(data.url, wptServer + 'google/google_csi.php?test=140101_AB_12');
done();
});
});
it('get google csi run 3 cached', function(done) {
wpt.getGoogleCsiData('140101_AB_12', {
dryRun: true,
repeatView: true,
run: 3
}, function(err, data) {
if (err) throw err;
assert.equal(data.url, wptServer + 'google/google_csi.php?test=140101_AB_12&run=3&cached=1');
done();
});
});
});
});
/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -5,0 +6,0 @@ */

@@ -53,2 +53,3 @@

--htmlbody save the content of only the base HTML response
--continuous capture video continuously (unstable/experimental, may cause tests to fail)
--poll [interval] poll for results after test is scheduled at every <interval> seconds [5]

@@ -55,0 +56,0 @@ --wait [hostname:port] wait for test results informed by agent once complete listening on <hostname>:<port> [hostname:first port available above 8000]

@@ -20,4 +20,8 @@

testinfo <id> get test request info/details
history [days] get history of previously run tests
googlecsi [options] <id> get Google CSI data (Client Side Instrumentation)
waterfall [options] <id> get the waterfall PNG image
screenshot [options] <id> get the fully loaded page screenshot in JPG format (PNG if in full resolution)
video [options] <tests> create a video from <tests> (comma separated test ids)
player <id> get a html5 player for a video <id>
listen [hostname:port] start webpagetest-api server on <hostname>:<port> [hostname:7791]

@@ -24,0 +28,0 @@ batch <file> run commands in batch, i.e. one command per line from <file> in parallel

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -28,2 +29,3 @@ */

'/getgzip.php?test=120816_V2_2&file=testinfo.json': 'testInfo.json',
'/testlog.php?all=on&f=csv&days=2': 'history.csv',
'/waterfall.php?test=120816_V2_2&run=1&cached=0': 'waterfall.png',

@@ -36,2 +38,6 @@ '/thumbnail.php?test=120816_V2_2&run=1&cached=0&file=1_waterfall.png': 'waterfallThumbnail.png',

'/cancelTest.php?test=120816_V2_3': 'cancelNotCancelled.html',
'/video/create.php?tests=130416_YS_KD4-r%3A3-c%3A1%2C130416_W6_KEE-r%3A8-c%3A1&f=json&end=visual': 'createVideo.json',
'/video/view.php?embed=1&id=130416_36ed6e37013655a14b2b857cdccec99db72adcaa': 'embeddedVideoPlayer.html',
'/google/google_csi.php?test=140101_AB_12': 'googleCsiData.csv',
'/google/google_csi.php?test=140101_AB_12&run=2': 'googleCsiDataRun2.csv',

@@ -38,0 +44,0 @@ // test results for multi runs with/without custom median metric

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -12,3 +13,3 @@ */

var reExtensions = /^\.(?:json|txt)$/i,
var reExtensions = /^\.(?:json|txt|html)$/i,
reJSONExt = /^\.json$/i,

@@ -15,0 +16,0 @@ reEOFNewLine = /\s+$/;

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -249,2 +250,11 @@ */

it('gets history GET request then returns the history JSON', function(done) {
get('/history/2', server, function (err, data) {
if (err) return done(err);
data = JSON.parse(data);
assert.deepEqual(data, ResponseObjects.history);
done();
});
});
it('gets a waterfall image GET request then returns the waterfall data URI string', function(done) {

@@ -251,0 +261,0 @@ get('/waterfall/120816_V2_2?uri=1', server, function (err, data) {

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -195,2 +196,10 @@ */

it('gets history request then returns the history object', function(done) {
wpt.getHistory(2, function (err, data) {
if (err) return done(err);
assert.deepEqual(data, ResponseObjects.history);
done();
});
});
it('gets a waterfall image request then returns the waterfall data URI string', function(done) {

@@ -250,2 +259,34 @@ wpt.getWaterfallImage('120816_V2_2', {dataURI: true}, function (err, data, info) {

it('creates a video', function (done) {
wpt.createVideo('130416_YS_KD4-r:3-c:1,130416_W6_KEE-r:8-c:1', {}, function (err, data) {
if (err) throw err;
assert.deepEqual(data, ResponseObjects.createVideo);
done();
});
});
it('gets the url of an embedded video', function (done) {
wpt.getEmbedVideoPlayer('130416_36ed6e37013655a14b2b857cdccec99db72adcaa', {}, function (err, data) {
if (err) throw err;
assert.equal(data, ResponseObjects.embeddedVideoPlayer + "\n");
done();
});
});
it('gets Google csi data', function(done) {
wpt.getGoogleCsiData('140101_AB_12', function(err, data) {
if (err) throw err;
assert.deepEqual(data, ResponseObjects.googleCsiData);
done();
});
});
it('gets Google csi data from run 2 only', function(done) {
wpt.getGoogleCsiData('140101_AB_12', {run: 2}, function(err, data) {
if (err) throw err;
assert.deepEqual(data, ResponseObjects.googleCsiDataRun2);
done();
});
});
// not found / invalid

@@ -252,0 +293,0 @@

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -5,0 +6,0 @@ */

/**
* Copyright (c) 2013, Twitter Inc.
* Copyright (c) 2013, Marcel Duran and other contributors
* Copyright (c) 2014, Google Inc.
* Copyright (c) 2014, Marcel Duran and other contributors
* Released under the MIT License

@@ -5,0 +6,0 @@ */

Sorry, the diff of this file is not supported yet

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