autocannon-reporter
Advanced tools
Comparing version 0.0.3 to 0.0.4
{ | ||
"name": "autocannon-reporter", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "A tool for creating html reports for autocannon", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
'use strict' | ||
const h = require('hyperscript') | ||
const hyperx = require('hyperx') | ||
const fs = require('fs') | ||
const path = require('path') | ||
const scripts = require('./partials/scripts') | ||
const css = require('./partials/css') | ||
const report = require('./partials/report') | ||
const css = fs.readFileSync(path.join(__dirname, './partials/main.css')) | ||
const flexboxgrid = fs.readFileSync(path.join(__dirname, './deps/flexboxgrid.min.css')) | ||
const chartistStyle = fs.readFileSync(path.join(__dirname, './deps/chartist.min.css')) | ||
const chartistScript = fs.readFileSync(path.join(__dirname, './deps/chartist.min.js')) | ||
module.exports = function (results) { | ||
const hx = hyperx(h) | ||
const tree = hx` | ||
const bodyTree = report(results) | ||
const fullBody = ` | ||
<!doctype html> | ||
@@ -20,9 +21,15 @@ <html> | ||
${flexboxgrid.toString()} | ||
${chartistStyle.toString()} | ||
${css.toString()} | ||
</style> | ||
${scripts(results, hx)} | ||
${css(results, hx)} | ||
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'> | ||
</head> | ||
<body> | ||
${report(results, hx)} | ||
${bodyTree.outerHTML} | ||
<script> | ||
${chartistScript.toString()} | ||
</script> | ||
<script> | ||
${scripts(results)} | ||
</script> | ||
</body> | ||
@@ -32,3 +39,3 @@ </html> | ||
return tree.outerHTML | ||
return fullBody | ||
} |
'use strict' | ||
const h = require('hyperscript') | ||
const hyperx = require('hyperx') | ||
const prettyBytes = require('pretty-bytes') | ||
@@ -9,3 +11,4 @@ const moment = require('moment') | ||
module.exports = function (results, hx) { | ||
module.exports = function (results) { | ||
const hx = hyperx(h) | ||
return hx` | ||
@@ -35,49 +38,70 @@ <div> | ||
</div> | ||
<div class='object latency'> | ||
<div class='heading' onclick="growDiv(this)"> | ||
<h2 class='symbol'>-</h2> | ||
<h2>Latency</h2> | ||
</div> | ||
<div class='content'> | ||
<div class='measuringWrapper'> | ||
<table class='table' style="width:100%"> | ||
<tr> | ||
<th>Stat</th> | ||
<th>Value</th> | ||
</tr> | ||
${ | ||
Object.keys(results.latency).map((key) => { | ||
return hx`<tr> | ||
<td>${key}</td> | ||
<td>${results.latency[key]}</td> | ||
</tr>` | ||
}) | ||
} | ||
</table> | ||
</div> | ||
</div> | ||
${results['2xx'] + results.non2xx > 0 ? panels(results, hx) : warnPanel(results, hx)} | ||
</div> | ||
</div> | ||
` | ||
} | ||
function panels (results, hx) { | ||
return hx` | ||
<div class='panels'> | ||
${responsePiePanel(results, hx)} | ||
${latencyTablePanel(results, hx)} | ||
${throughputTablePanel(results, hx)} | ||
</div> | ||
` | ||
} | ||
function latencyTablePanel (results, hx) { | ||
return hx` | ||
<div class='object latency'> | ||
<div class='heading' onclick="growDiv(this)"> | ||
<h2 class='symbol'>-</h2> | ||
<h2>Latency</h2> | ||
</div> | ||
<div class='content'> | ||
<div class='measuringWrapper'> | ||
<table class='table' style="width:100%"> | ||
<tr> | ||
<th>Stat</th> | ||
<th>Value</th> | ||
</tr> | ||
${ | ||
Object.keys(results.latency).map((key) => { | ||
return hx`<tr> | ||
<td>${key}</td> | ||
<td>${results.latency[key]}</td> | ||
</tr>` | ||
}) | ||
} | ||
</table> | ||
</div> | ||
<div class='object throughput'> | ||
<div class='heading' onclick="growDiv(this)"> | ||
<h2 class='symbol'>-</h2> | ||
<h2>Throughput</h2> | ||
</div> | ||
<div class='content'> | ||
<div class='measuringWrapper'> | ||
<table class='table' style="width:100%"> | ||
<tr> | ||
<th>Stat</th> | ||
<th>Value</th> | ||
</tr> | ||
${ | ||
Object.keys(results.throughput).map((key) => { | ||
return hx`<tr> | ||
<td>${key}</td> | ||
<td>${prettyBytes(results.throughput[key])}</td> | ||
</tr>` | ||
}) | ||
} | ||
</table> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
` | ||
} | ||
function throughputTablePanel (results, hx) { | ||
return hx` | ||
<div class='object throughput'> | ||
<div class='heading' onclick="growDiv(this)"> | ||
<h2 class='symbol'>-</h2> | ||
<h2>Throughput</h2> | ||
</div> | ||
<div class='content'> | ||
<div class='measuringWrapper'> | ||
<table class='table' style="width:100%"> | ||
<tr> | ||
<th>Stat</th> | ||
<th>Value</th> | ||
</tr> | ||
${ | ||
Object.keys(results.throughput).map((key) => { | ||
return hx`<tr> | ||
<td>${key}</td> | ||
<td>${prettyBytes(results.throughput[key])}</td> | ||
</tr>` | ||
}) | ||
} | ||
</table> | ||
</div> | ||
@@ -88,1 +112,33 @@ </div> | ||
} | ||
function warnPanel (results, hx) { | ||
return hx` | ||
<div class='object'> | ||
<div class='heading' onclick="growDiv(this)"> | ||
<h2 class='symbol'>-</h2> | ||
<h2>Warning</h2> | ||
</div> | ||
<div class='content'> | ||
<div class='measuringWrapper'> | ||
<h3 color='red'>No graphs to display because of failed autocannon run (0 responses received)</h3> | ||
</div> | ||
</div> | ||
</div> | ||
` | ||
} | ||
function responsePiePanel (results, hx) { | ||
return hx ` | ||
<div class='object reponsePie'> | ||
<div class='heading' onclick="growDiv(this)"> | ||
<h2 class='symbol'>-</h2> | ||
<h2>Response Types Piechart</h2> | ||
</div> | ||
<div class='content graph'> | ||
<div class='measuringWrapper'> | ||
<div class="ct-chart ct-perfect-fourth"></div> | ||
</div> | ||
</div> | ||
</div> | ||
` | ||
} |
'use strict' | ||
module.exports = function (results, hx) { | ||
// put any clientside interactivity scripts between script tags | ||
// if minified libs needed, read them sync and put the buffer.toString | ||
// in there | ||
return hx` | ||
<script> | ||
function growDiv(e) { | ||
var header = e | ||
var objectContainer = header.parentElement | ||
var symbol = objectContainer.getElementsByClassName("symbol")[0] | ||
var content = objectContainer.getElementsByClassName("content")[0] | ||
if (content.clientHeight !== 20) { | ||
content.style.height = 0; | ||
symbol.innerText = '+' | ||
} else { | ||
var wrapper = content.getElementsByClassName("measuringWrapper")[0] | ||
content.style.height = wrapper.clientHeight + "px"; | ||
symbol.innerText = '-' | ||
module.exports = function (results) { | ||
return ` | ||
var results = ${JSON.stringify(results)} | ||
${growDiv.toString()} | ||
${main.toString()} | ||
main(Chartist, results) | ||
` | ||
} | ||
function main (chartist, results) { | ||
var labels = ['1xx', '2xx', '3xx', '4xx', '5xx', 'non2xx', 'timeouts'] | ||
var nonZeros = [] | ||
var seriesValues = [] | ||
var options = { | ||
fullWidth: true, | ||
height: 450 | ||
} | ||
var responsiveOptions = [ | ||
['screen and (min-width: 640px)', { | ||
chartPadding: 30, | ||
labelOffset: 110, | ||
labelDirection: 'explode', | ||
labelInterpolationFnc: function (value) { | ||
return value | ||
} | ||
}], | ||
['screen and (min-width: 1024px)', { | ||
labelOffset: 90, | ||
chartPadding: 20 | ||
}] | ||
] | ||
labels.forEach(function (label) { | ||
if (results[label] !== 0) { | ||
nonZeros.push(label) | ||
} | ||
}) | ||
nonZeros.forEach(function (value) { | ||
seriesValues.push(results[value]) | ||
}) | ||
chartist.Pie('.ct-chart', { | ||
labels: nonZeros, | ||
series: seriesValues | ||
}, options, responsiveOptions) | ||
} | ||
function growDiv (e) { | ||
var header = e | ||
var objectContainer = header.parentElement | ||
var symbol = objectContainer.getElementsByClassName('symbol')[0] | ||
var content = objectContainer.getElementsByClassName('content')[0] | ||
if (content.clientHeight !== 20) { | ||
content.style.height = 0 | ||
symbol.innerText = '+' | ||
} else { | ||
var wrapper = content.getElementsByClassName('measuringWrapper')[0] | ||
content.style.height = wrapper.clientHeight + 'px' | ||
symbol.innerText = '-' | ||
} | ||
</script> | ||
` | ||
} |
@@ -9,4 +9,6 @@ 'use strict' | ||
const sampleResult = require('./sampleResult.json') | ||
const warningSample = require('./warningSample.json') | ||
const moment = require('moment') | ||
const report = autocannonReporter.buildReport(sampleResult) | ||
const warningReport = autocannonReporter.buildReport(warningSample) | ||
const expect = Code.expect | ||
@@ -24,2 +26,7 @@ | ||
lab.test('Report output should contain warning', (done) => { | ||
expect(warningReport).to.contain('No graphs to display because of failed autocannon run (0 responses received)') | ||
done() | ||
}) | ||
lab.test('Report output should contain the average throughput in text', (done) => { | ||
@@ -26,0 +33,0 @@ expect(report).to.contain(prettyBytes(sampleResult.throughput.average)) |
@@ -36,8 +36,8 @@ { | ||
"pipelining": 1, | ||
"non2xx": 0, | ||
"1xx": 0, | ||
"2xx": 186217, | ||
"3xx": 0, | ||
"4xx": 0, | ||
"5xx": 0 | ||
"non2xx": 880, | ||
"1xx": 300, | ||
"2xx": 100, | ||
"3xx": 80, | ||
"4xx": 250, | ||
"5xx": 150 | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
82900
18
692