Skip to content

Commit

Permalink
report(flow): standalone shell report with preact (#12850)
Browse files Browse the repository at this point in the history
Co-authored-by: Patrick Hulce <[email protected]>
  • Loading branch information
adamraine and patrickhulce authored Aug 18, 2021
1 parent abda702 commit 46d282b
Show file tree
Hide file tree
Showing 28 changed files with 13,918 additions and 18 deletions.
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ results.html
# generated files needed for publish
dist/**
!dist/report/standalone.js
!dist/report/flow.js

# large files
changelog.md
Expand Down
2 changes: 2 additions & 0 deletions build/build-lightrider-bundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ function buildEntryPoint() {
*/
function buildReportGenerator() {
browserify(generatorFilename, {standalone: 'ReportGenerator'})
// Flow report is not used in LR, so don't include flow assets.
.ignore(require.resolve('../report/flow-report-assets.js'))
// Transform the fs.readFile etc into inline strings.
.transform('@wardpeet/brfs', {
readFileTransform: minifyFileTransform,
Expand Down
35 changes: 35 additions & 0 deletions build/build-report.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
'use strict';

const rollup = require('rollup');
const {nodeResolve} = require('@rollup/plugin-node-resolve');
const {terser} = require('rollup-plugin-terser');
// Only needed b/c getFilenamePrefix loads a commonjs module.
const commonjs =
// @ts-expect-error types are wrong.
/** @type {import('rollup-plugin-commonjs').default} */ (require('rollup-plugin-commonjs'));

/**
* @type {import('rollup-plugin-typescript2').default}
*/
const typescript = require('rollup-plugin-typescript2');

async function buildStandaloneReport() {
const bundle = await rollup.rollup({
input: 'report/clients/standalone.js',
Expand All @@ -27,6 +33,32 @@ async function buildStandaloneReport() {
});
}

async function buildFlowReport() {
const bundle = await rollup.rollup({
input: 'flow-report/standalone-flow.tsx',
plugins: [
nodeResolve(),
commonjs(),
typescript({
tsconfig: 'flow-report/tsconfig.json',
// rollup-plugin-commonjs 10.1.0 does not work here.
// https://github.com/ezolenko/rollup-plugin-typescript2#plugin-options
tsconfigOverride: {
compilerOptions: {
module: 'ES6',
},
},
}),
terser(),
],
});

await bundle.write({
file: 'dist/report/flow.js',
format: 'iife',
});
}

async function buildPsiReport() {
const bundle = await rollup.rollup({
input: 'report/clients/psi.js',
Expand Down Expand Up @@ -73,6 +105,7 @@ async function buildUmdBundle() {
if (require.main === module) {
if (process.argv.length <= 2) {
buildStandaloneReport();
buildFlowReport();
buildEsModulesBundle();
buildPsiReport();
buildUmdBundle();
Expand All @@ -83,6 +116,7 @@ if (require.main === module) {
}
if (process.argv.includes('--standalone')) {
buildStandaloneReport();
buildFlowReport();
}
if (process.argv.includes('--esm')) {
buildEsModulesBundle();
Expand All @@ -94,6 +128,7 @@ if (require.main === module) {

module.exports = {
buildStandaloneReport,
buildFlowReport,
buildPsiReport,
buildUmdBundle,
};
2 changes: 2 additions & 0 deletions build/build-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ async function run() {
// JS bundle from browserified ReportGenerator.
const generatorFilename = `${LH_ROOT}/report/report-generator.js`;
const generatorBrowserify = browserify(generatorFilename, {standalone: 'ReportGenerator'})
// Flow report is not used in report viewer, so don't include flow assets.
.ignore(require.resolve('../report/flow-report-assets.js'))
.transform('@wardpeet/brfs', {
readFileTransform: minifyFileTransform,
});
Expand Down
30 changes: 30 additions & 0 deletions flow-report/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @license Copyright 2021 The Lighthouse Authors. 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.
*/

module.exports = {
extends: '../.eslintrc.js',
env: {
node: true,
browser: true,
},
overrides: [
// TS already handles this issue.
// https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
{
files: ['**/*.ts', '**/*.tsx'],
rules: {
'no-undef': 'off',
},
},
],
parserOptions: {
ecmaVersion: 2019,
ecmaFeatures: {
jsx: true,
},
sourceType: 'module',
},
};
42 changes: 42 additions & 0 deletions flow-report/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @license Copyright 2021 The Lighthouse Authors. 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.
*/

import {FunctionComponent} from 'preact';
import {useState} from 'preact/hooks';

export const Report: FunctionComponent<{lhr: LH.Result}> = ({lhr}) => {
// TODO(FR-COMPAT): Render an actual report here.
return (
<div>
<h1>{lhr.finalUrl}</h1>
{
Object.values(lhr.categories).map((category) =>
<h2>{category.id}: {category.score}</h2>
)
}
</div>
);
};

export const App: FunctionComponent<{flowResult: LH.FlowResult}> = ({flowResult}) => {
const [currentLhrIndex, setCurrentLhrIndex] = useState(0);
return (
<>
<select onChange={e => setCurrentLhrIndex(Number(e.currentTarget.value))}>
{
flowResult.lhrs.map((lhr, i) =>
<option key={lhr.fetchTime} value={i}>
[{lhr.fetchTime}] [{lhr.gatherMode}] {lhr.finalUrl}
</option>
)
}
</select>
<div>
<Report lhr={flowResult.lhrs[currentLhrIndex]}/>
</div>
</>
);
};
37 changes: 37 additions & 0 deletions flow-report/assets/standalone-flow-template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!--
@license
Copyright 2021 The Lighthouse Authors. 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.
-->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEhklEQVR4AWJxL/BhIAesev1U5tcflpncgNrKIsqNIwzC9feMpDUzs70kOczMzMzJJcxwCTMzncPMnOwtzBwzMzPb0vRfeZPp0VhPS5I39V5fdiXV1/VD+9QC7OVn9BsyH1XIoEI1PfmJvLFowVV564+34DFUHudbmfDh4kVXh//7XwE+WjS/YfXZe3yr4j2rqj1AIhSB7hZ8ZtPZu/zw8cK523U4wE1/rvPfWrz4zs0m9ZdC9yUJAlASdBAgocRegfF/f3/h/PuaFsxMdwjAR0vm1+06eMMfIrhLqTWqdH4EumU2SPfMhigJAlRQbZrgrRsl9U+Y2DYDFCz3ILC9kiAiqSrMwbWT0nceEnR+9Kggc2zjOJCASDENkg0a5HfZZgDP81CM3CrQs2Z1+o7DJ6ePr8sK0AOCHv5Jjdt3evyYSaZ351VIStIxPRAUtrBYbxC6w+BZ0ivVSBKkIhJhemSyZpfB00EiPO2VjzYkxhcqXQqCWCShGplvi3y0QxqbuBurMjyJeWnkHZuAEgIQGsUBqwrfjZ+IlBgKyRJzVVYF8O6qFWdh86YzQzMrZigYmxAyfvHgLZQ/LC1CbeniW2Hkqr/PH16SgvGuf2/uzNMBwJA/njxizGPtSyAf7EziJCMGRDRdhoAC4PL1A/SrKQMAAQkEfpJAcRQdrBJ7gNwjSpJsdwK+CANBkqa1LgQB4IicV9nYUct7gaxuDJUErQIiEAiMxLVOFlKzIktPpT0ggpdpC/8YAHnxbgkUY4tAAFSR7AAXNyAAWHJrA/kHGjzg5nleuwFO7Nd/IoDw4Pm58+4jNLmYG0wRA5bErc2Mr3Y+dXTDW1VvwqbJkzMCHQ4S1GTCBOIgUHJrGdEwqzR+jAp/o2qAZelUDoQnruEEdDclJI6576AlNVfc+22XN/+Y1vnJD0Yind6UpEEvn/Hqq15EYjCW7jZCJEpnNvDgkyelDjs106kuux2AAXCSobULOWP8mLhYlpoDMK4qAFXJGk+grtH8YXVz5KJblqaG1+VUdTc0I290bmUQAriGITRbdQnom0aoFj8kx1+wMD2ifncAXUQE4SkDqN1hE0jEophs1SUwZAOhUAiMCLwRtamtTZtbbmZErSAUHbSysaoEmnrsakiMiUAURi283gN6wans9oX8rOCrj7/JP35DFD+iQ7Au/K2KE1jzx6ujjUnXFH9KjEq6ZlhsTBICrNLJf47Pv/pkHzvup1w4dmUbEei0+bcXRqJuh5kVARQ8byyYxOwNGr7A87xh1tp8sGT+uMInrwi++Xj7TQz2d27NvwEkrOflAFQGIDA5khASBCGdO2/Z/MnLPwYfv5TFhjW7QhVKAB6afwe2LpFlFsCnlQEosgQgDsdOG1/LKeNqJS4JCSPJ/i+TakwEARor7gER1Iva5JmPOJK0RUqmoPnnlzFCtmIAhAAQEIQRgDaiYPIauNXcnDlRIrWNFY3hm7PG9YRqr7IV7HrCgAC17befjEvRq2nGhAHtBqDpOuI/I1diUUAMYIxEdyejBJqLnNoszGZtfiX/CztGv2mq+sdaAAAAAElFTkSuQmCC">
<title>Lighthouse Flow Report</title>
<style>/*%%LIGHTHOUSE_CSS%%*/</style>
</head>
<body class="lh-root lh-vars">
<noscript>Lighthouse report requires JavaScript. Please enable.</noscript>

<main><!-- report populated here --></main>

<script>window.__LIGHTHOUSE_FLOW_JSON__ = %%LIGHTHOUSE_FLOW_JSON%%;</script>
<script>%%LIGHTHOUSE_FLOW_JAVASCRIPT%%
__initLighthouseFlowReport__();
</script>
<script>console.log('window.__LIGHTHOUSE_FLOW_JSON__', __LIGHTHOUSE_FLOW_JSON__);</script>
</body>
</html>
13 changes: 13 additions & 0 deletions flow-report/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @license Copyright 2021 The Lighthouse Authors. 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.
*/

module.exports = {
testEnvironment: 'jsdom',
preset: 'ts-jest',
testMatch: [
'**/test/**/*-test.tsx',
],
};
22 changes: 22 additions & 0 deletions flow-report/standalone-flow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @license Copyright 2021 The Lighthouse Authors. 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.
*/

/**
* @fileoverview The entry point for rendering the Lighthouse flow report for the HTML file created by ReportGenerator.
* The renderer code is bundled and injected into the report HTML along with the JSON report.
*/

import {render} from 'preact';
import {App} from './App';

// Used by standalone-flow.html
function __initLighthouseFlowReport__() {
const root = document.body.querySelector('main');
if (!root) throw Error('Root element not found');
render(<App flowResult={window.__LIGHTHOUSE_FLOW_JSON__} />, root);
}

window.__initLighthouseFlowReport__ = __initLighthouseFlowReport__;
28 changes: 28 additions & 0 deletions flow-report/test/App-test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @license Copyright 2021 The Lighthouse Authors. 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.
*/

import fs from 'fs';
import {App} from '../App';
import {render} from '@testing-library/preact';
import {LH_ROOT} from '../../root';

const flowResult = JSON.parse(
fs.readFileSync(
`${LH_ROOT}/lighthouse-core/test/fixtures/fraggle-rock/reports/sample-lhrs.json`,
'utf-8'
)
);

it('Renders a standalone report', async () => {
const root = render(<App flowResult={flowResult}/>);
const navigation = await root.findByText(/navigation/);
const timespan = await root.findByText(/timespan/);
const snapshot = await root.findByText(/snapshot/);

expect(navigation.innerHTML).toEqual('[2021-08-03T18:28:13.296Z] [navigation] https://www.mikescerealshack.co/');
expect(timespan.innerHTML).toEqual('[2021-08-03T18:28:31.789Z] [timespan] https://www.mikescerealshack.co/search?q=call+of+duty');
expect(snapshot.innerHTML).toEqual('[2021-08-03T18:28:36.856Z] [snapshot] https://www.mikescerealshack.co/search?q=call+of+duty');
});
14 changes: 14 additions & 0 deletions flow-report/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "../tsconfig",
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact",
"esModuleInterop": true,
"composite": false
},
"include": [
"**/*.tsx",
"./types",
"../types"
],
}
16 changes: 16 additions & 0 deletions flow-report/types/flow-report.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @license Copyright 2021 The Lighthouse Authors. 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.
*/

import FlowResult from '../../types/lhr/flow';

declare global {
interface Window {
__LIGHTHOUSE_FLOW_JSON__: FlowResult;
__initLighthouseFlowReport__: () => void;
}
}

export {};
4 changes: 4 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@ module.exports = {
],
transform: {},
prettierPath: null,
projects: [
'<rootDir>',
'<rootDir>/flow-report',
],
};
3 changes: 3 additions & 0 deletions lighthouse-core/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ class Runner {

/** @type {LH.RawIcu<LH.Result>} */
const i18nLhr = {
// TODO(FR-COMPAT): Make GatherContext a true base artifact.
// If GatherContext is not collected, then we are in a non-default pass of the legacy runner.
gatherMode: artifacts.GatherContext ? artifacts.GatherContext.gatherMode : 'navigation',
userAgent: artifacts.HostUserAgent,
environment: {
networkUserAgent: artifacts.NetworkUserAgent,
Expand Down
23 changes: 23 additions & 0 deletions lighthouse-core/scripts/build-test-flow-report.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @license Copyright 2021 The Lighthouse Authors. 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 open = require('open');
const {execFileSync} = require('child_process');

execFileSync(`yarn`, ['build-report']);
const reportGenerator = require('../../report/report-generator.js');

const flow = JSON.parse(fs.readFileSync(
`${__dirname}/../test/fixtures/fraggle-rock/reports/sample-lhrs.json`,
'utf-8')
);

const htmlReport = reportGenerator.generateFlowReportHtml(flow);

fs.writeFileSync(`${__dirname}/../../flow.report.html`, htmlReport);
open(`${__dirname}/../../flow.report.html`);
Loading

0 comments on commit 46d282b

Please sign in to comment.