diff --git a/lighthouse-cli/bin.ts b/lighthouse-cli/bin.ts index edd44142fbf6..5cab8417b8ea 100755 --- a/lighthouse-cli/bin.ts +++ b/lighthouse-cli/bin.ts @@ -83,18 +83,17 @@ const cliFlags = yargs 'port': 'The port to use for the debugging protocol. Use 0 for a random port', 'skip-autolaunch': 'Skip autolaunch of Chrome when already running instance is not found', 'select-chrome': 'Interactively choose version of Chrome to use when multiple installations are found', + 'interactive': 'Open Lighthouse in interactive mode' }) .group([ 'output', - 'output-path', - 'view' + 'output-path' ], 'Output:') .describe({ 'output': 'Reporter for the results', 'output-path': `The file path to output the results -Example: --output-path=./lighthouse-results.html`, - 'view': 'Open report.html in browser' +Example: --output-path=./lighthouse-results.html` }) // boolean values @@ -112,7 +111,7 @@ Example: --output-path=./lighthouse-results.html`, 'verbose', 'quiet', 'help', - 'view' + 'interactive' ]) .choices('output', Printer.GetValidOutputOptions()) @@ -251,7 +250,7 @@ function handleError(err: LighthouseError) { function runLighthouse(url: string, flags: {port: number, skipAutolaunch: boolean, selectChrome: boolean, output: any, - outputPath: string, view: boolean, saveArtifacts: boolean, saveAssets: boolean}, + outputPath: string, interactive: boolean, saveArtifacts: boolean, saveAssets: boolean}, config: Object): Promise { let chromeLauncher: ChromeLauncher; @@ -281,8 +280,8 @@ function runLighthouse(url: string, return results; }) .then((results: Results) => { - if (flags.view) { - return performanceXServer.serveAndOpenReport({url, flags, config}, results); + if (flags.interactive) { + return performanceXServer.hostExperiment({url, flags, config}, results); } }) .then(() => chromeLauncher.kill()) diff --git a/lighthouse-cli/performance-experiment/report/injected-script.js b/lighthouse-cli/performance-experiment/report/injected-script.js new file mode 100644 index 000000000000..1e6f7c0cd15b --- /dev/null +++ b/lighthouse-cli/performance-experiment/report/injected-script.js @@ -0,0 +1,50 @@ +/** + * @license + * Copyright 2016 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* global window, document, location */ + +'use strict'; + +/** + * @fileoverview Report script for Project Performance Experiment. + * + * Include functions for supporting interation between report page and Perf-X server. + */ + +window.addEventListener('DOMContentLoaded', _ => { + const rerunButton = document.querySelector('.js-rerun-button'); + rerunButton.style.display = 'inline-block'; + + rerunButton.addEventListener('click', () => { + rerunButton.setAttribute('status', 'running'); + rerunLighthouse().then(() => { + location.reload(); + }); + }); +}); + +/** + * Send POST request to rerun lighthouse. + * Available additionalFlags attributes: + * - blockedUrlPatterns {Array} Block all the URL patterns. + * + * @param {!Object} additionalFlags + * @return {!Promise} resolve when rerun is completed + */ +function rerunLighthouse(additionalFlags={}) { + return fetch('/rerun', {method: 'POST', body: JSON.stringify(additionalFlags)}); +} diff --git a/lighthouse-cli/performance-experiment/report/perf-x-report-generator.js b/lighthouse-cli/performance-experiment/report/perf-x-report-generator.js new file mode 100644 index 000000000000..ef6aeb10bc93 --- /dev/null +++ b/lighthouse-cli/performance-experiment/report/perf-x-report-generator.js @@ -0,0 +1,33 @@ +/** + * @license + * Copyright 2016 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const ReportGenerator = require('../../../lighthouse-core/report/report-generator'); + +class PerfXReportGenerator extends ReportGenerator { + getReportJS(reportContext) { + const scriptArr = super.getReportJS(reportContext); + scriptArr.push(fs.readFileSync(path.join(__dirname, './injected-script.js'), 'utf8')); + return scriptArr; + } +} + +module.exports = PerfXReportGenerator; diff --git a/lighthouse-cli/performance-experiment/server.js b/lighthouse-cli/performance-experiment/server.js index 165f4e84b7c8..85f9e34e4928 100644 --- a/lighthouse-cli/performance-experiment/server.js +++ b/lighthouse-cli/performance-experiment/server.js @@ -20,25 +20,32 @@ * @fileoverview Server script for Project Performance Experiment. * * Functionality: - * Host and open report page. + * Host experiment. + * Report can be access via URL http://localhost:[PORT]/ + * Rerun data can be access via URL http://localhost:[PORT]/rerun. + * This will rerun lighthouse with same parameters and rerun results in JSON format */ const http = require('http'); const parse = require('url').parse; -const path = require('path'); const opn = require('opn'); const log = require('../../lighthouse-core/lib/log'); -const ReportGenerator = require('../../lighthouse-core/report/report-generator'); +const reportGenerator = new (require('./report/perf-x-report-generator'))(); +const lighthouse = require('../../lighthouse-core'); + /** * Start the server with an arbitrary port and open report page in the default browser. - * @param {!Object} lighthouseParams + * @param {!Object} params A JSON contains lighthouse parameters * @param {!Object} results * @return {!Promise} Promise that resolves when server is closed */ let lhResults; -function serveAndOpenReport(lighthouseParams, results) { +let lhParams; +function hostExperiment(params, results) { lhResults = results; + lhParams = params; + return new Promise(resolve => { const server = http.createServer(requestHandler); server.listen(0); @@ -54,25 +61,51 @@ function serveAndOpenReport(lighthouseParams, results) { } function requestHandler(request, response) { - const pathname = path.normalize(parse(request.url).pathname); + const pathname = parse(request.url).pathname; - if (pathname === '/') { - reportRequestHandler(request, response); + if (request.method === 'GET') { + if (pathname === '/') { + reportRequestHandler(request, response); + } else { + response.writeHead(404); + response.end('404: Resource Not Found'); + } + } else if (request.method === 'POST') { + if (pathname === '/rerun') { + rerunRequestHandler(request, response); + } else { + response.writeHead(404); + response.end('404: Resource Not Found'); + } } else { - response.writeHead(400); - response.write('400 - Bad request'); - response.end(); + response.writeHead(405); + response.end('405: Method Not Supported'); } } function reportRequestHandler(request, response) { - const reportGenerator = new ReportGenerator(); const html = reportGenerator.generateHTML(lhResults, 'cli'); response.writeHead(200, {'Content-Type': 'text/html'}); - response.write(html); - response.end(); + response.end(html); +} + +function rerunRequestHandler(request, response) { + let message = ''; + request.on('data', data => message += data); + + request.on('end', () => { + const additionalFlags = JSON.parse(message); + const flags = Object.assign({}, lhParams.flags, additionalFlags); + + lighthouse(lhParams.url, flags, lhParams.config).then(results => { + results.artifacts = undefined; + lhResults = results; + response.writeHead(200); + response.end(); + }); + }); } module.exports = { - serveAndOpenReport + hostExperiment }; diff --git a/lighthouse-core/report/report-generator.js b/lighthouse-core/report/report-generator.js index 5f224fcfab48..ba0a78de57ea 100644 --- a/lighthouse-core/report/report-generator.js +++ b/lighthouse-core/report/report-generator.js @@ -203,10 +203,15 @@ class ReportGenerator { /** * Gets the script for the report UI - * @return {string} + * @param {string} reportContext + * @return {Array} an array of scripts */ - getReportJS() { - return fs.readFileSync(path.join(__dirname, './scripts/lighthouse-report.js'), 'utf8'); + getReportJS(reportContext) { + if (reportContext === 'devtools') { + return []; + } else { + return [fs.readFileSync(path.join(__dirname, './scripts/lighthouse-report.js'), 'utf8')]; + } } /** @@ -304,7 +309,7 @@ class ReportGenerator { lhresults: this._escapeScriptTags(JSON.stringify(results, null, 2)), css: this.getReportCSS(), reportContext: reportContext, - script: reportContext === 'devtools' ? '' : this.getReportJS(), + scripts: this.getReportJS(reportContext), aggregations: results.aggregations, auditsByCategory: this._createPWAAuditsByCategory(results.aggregations) }); diff --git a/lighthouse-core/report/styles/report.css b/lighthouse-core/report/styles/report.css index 0c9c56e4787d..0903935ea8ab 100644 --- a/lighthouse-core/report/styles/report.css +++ b/lighthouse-core/report/styles/report.css @@ -145,6 +145,29 @@ body { display: none; } +.report-body__icon.copy { + background-image: url('data:image/svg+xml;utf8,'); + display: none; +} + +.report-body__icon.rerun-button { + background-image: url('data:image/svg+xml;utf8,'); + display: none; +} + +.rerun-button[status=running] { + animation: rotate 1000ms infinite; +} + +@keyframes rotate { + from { + transform: none; + } + to { + transform: rotate(360deg); + } +} + .score-container__overall-score { color: #FFF; font-size: 92px; diff --git a/lighthouse-core/report/templates/report-template.html b/lighthouse-core/report/templates/report-template.html index 9a4981e36fa5..fb2d2955ed68 100644 --- a/lighthouse-core/report/templates/report-template.html +++ b/lighthouse-core/report/templates/report-template.html @@ -24,14 +24,14 @@ Lighthouse report: {{ url }} - {{#if script }} - - {{/if}} + {{#each scripts }} + + {{/each}}
-
+