From 5eb09fac592101d714dc6b7efe43eca998138908 Mon Sep 17 00:00:00 2001 From: Rodrigo Medeiros Date: Mon, 23 Aug 2021 10:23:06 -0300 Subject: [PATCH] Add option to export to file (#128) --- .gitignore | 1 + README.md | 21 +++++++++++++++++ cli.js | 2 ++ lib/options-handler.js | 1 + lib/output.js | 44 ++++++++++++++++++++++++++++++++---- test/format.test.js | 2 +- test/options-handler.test.js | 24 +++++++++++++++++++- 7 files changed, 89 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index c7e268f..8468fb1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules yarn.lock .nyc_output/ coverage/ +.history/ diff --git a/README.md b/README.md index 81a9d9d..0e48ebf 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,27 @@ Values: `mobile` `desktop` Strategy to use when analyzing the page. +##### format + +Type: `string`
+Default: `cli`
+Values: `cli` `tap` `json` + +Report output format. + +##### toFile + +Type: `boolean`
+Default: `false` + +Defines whether the report output will be in files. Only works if combined with Json format. + +##### filePath + +Type: `string`
+ +Path to generated file. Only works if combined with toFile option. + ##### locale Type: `string`
diff --git a/cli.js b/cli.js index 34adda6..1e85adc 100755 --- a/cli.js +++ b/cli.js @@ -13,6 +13,8 @@ const cli = meow(` --key Google API Key. By default the free tier is used --strategy Strategy to use when analyzing the page: mobile|desktop --format Output format: cli|json|tap + --toFile Output report in files. Only works if combined with Json format + --filePath Path to generated file. Only works if combined with toFile option --locale Locale results should be generated in --threshold Threshold score to pass the PageSpeed test --links Adds link with more info about opportunities diff --git a/lib/options-handler.js b/lib/options-handler.js index 8454b8e..e8d910b 100644 --- a/lib/options-handler.js +++ b/lib/options-handler.js @@ -6,6 +6,7 @@ const getOptions = (url, options) => { options = Object.assign({strategy: 'mobile'}, options); options.nokey = options.key === undefined; options.url = prependHttp(url); + options.toFile = options.toFile !== undefined && options.toFile !== false; return options; }; diff --git a/lib/output.js b/lib/output.js index 74971b0..a82e9ad 100644 --- a/lib/output.js +++ b/lib/output.js @@ -5,6 +5,7 @@ const prettyMs = require('pretty-ms'); const terminalLink = require('terminal-link'); const {getThreshold, getReporter} = require('./../lib/options-handler'); const {getLink} = require('./../lib/string-utils'); +const fs = require('fs'); function overview(url, strategy, scores) { return [ @@ -89,20 +90,55 @@ const opportunities = (lighthouseResult, links) => { }; const convertToPercentum = num => Math.round(num * 100); +const isInTest = typeof global.it === 'function'; module.exports = (parameters, response) => { return Promise.resolve().then(() => { - const renderer = require(`./formats/${getReporter(parameters.format)}`); + const {format, strategy, filePath} = parameters; + + const renderer = require(`./formats/${getReporter(format)}`); const threshold = getThreshold(parameters.threshold); const {lighthouseResult, loadingExperience = {}, id} = response; + const humanizedUrl = humanizeUrl(id); - console.log(renderer( - overview(humanizeUrl(id), parameters.strategy, lighthouseResult), + const render = renderer( + overview(humanizedUrl, strategy, lighthouseResult), fieldData(loadingExperience.metrics), labData(lighthouseResult), opportunities(lighthouseResult, parameters.links), threshold - )); + ); + + console.log(render); + + if (parameters.toFile && format === 'json' && !isInTest) { + const urlFilename = humanizedUrl.replaceAll('.', '-').replaceAll('/', '--'); + + const dateFilename = new Date() + .toISOString() + .slice(0, 19) + .replace(/\D/g, ''); + + const jsonFileName = `${filePath ? filePath + '/' : ''}${urlFilename}_${strategy}_${dateFilename}`; + + const responseJsonStringfy = JSON.stringify(response); + + fs.writeFileSync(`${jsonFileName}_short.json`, render, err => { + if (err) { + return console.error(err); + } + }); + + fs.writeFileSync( + `${jsonFileName}_full.json`, + responseJsonStringfy, + err => { + if (err) { + return console.error(err); + } + } + ); + } const score = convertToPercentum(lighthouseResult.categories.performance.score); if (score < threshold) { diff --git a/test/format.test.js b/test/format.test.js index 8e9c458..cb6f7b2 100644 --- a/test/format.test.js +++ b/test/format.test.js @@ -3,7 +3,7 @@ const {assert} = require('chai'); const stripAnsi = require('strip-ansi'); const output = require('../lib/output'); -const response = require('./fixtures/response'); +const response = require('./fixtures/response.json'); describe('Formatting', () => { beforeEach(function () { diff --git a/test/options-handler.test.js b/test/options-handler.test.js index 08e7350..f6861f5 100644 --- a/test/options-handler.test.js +++ b/test/options-handler.test.js @@ -7,7 +7,9 @@ describe('Options handler method', () => { describe('getOptions method', () => { const defaultConfig = { nokey: true, - url: 'http://addyosmani.com' + url: 'http://addyosmani.com', + strategy: 'mobile', + toFile: false }; it('should return strategy "mobile" if no strategy is passed', () => { const expectedOutput = { @@ -23,6 +25,26 @@ describe('Options handler method', () => { }; expect(getOptions('http://addyosmani.com', {strategy: 'desktop'})).to.eql(expectedOutput); }); + it('should return toFile "false" if is not specificied', () => { + const expectedOutput = { + ...defaultConfig + }; + expect(getOptions('http://addyosmani.com')).to.eql(expectedOutput); + }); + it('should return toFile "true" if is specificied', () => { + const expectedOutput = { + ...defaultConfig, + toFile: true + }; + expect(getOptions('http://addyosmani.com', {toFile: true})).to.eql(expectedOutput); + }); + it('should return "~/" as path to file', () => { + const expectedOutput = { + ...defaultConfig, + filePath: '~/' + }; + expect(getOptions('http://addyosmani.com', {filePath: '~/'})).to.eql(expectedOutput); + }); }); describe('getThreshold method', () => {