Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

report: create faux psi report #12815

Merged
merged 30 commits into from
Aug 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
60e38ee
report api. (and psi thinger)
paulirish Jul 9, 2021
9d0326b
cleanup
paulirish Jul 10, 2021
f059abd
'proper' psi variant
paulirish Jul 10, 2021
da84011
Merge remote-tracking branch 'origin/master' into reportapi
paulirish Jul 20, 2021
c18bd48
fixup psi dist
paulirish Jul 20, 2021
349a655
new tabs. distinguished screenshots
paulirish Jul 21, 2021
f6003b6
Merge remote-tracking branch 'origin/master' into reportapi
paulirish Jul 21, 2021
4c2f18f
cleanup psi more
paulirish Jul 21, 2021
27e21f4
report: create faux psi report
paulirish Jul 21, 2021
1bdd6e3
drop types
paulirish Jul 21, 2021
47e6f15
await the buildpsi
paulirish Jul 21, 2021
2003340
no need to doublebuild
paulirish Jul 21, 2021
9df8212
html-report-assets is a runtime dep that depends on a built asset. sq…
paulirish Jul 21, 2021
131ef40
tweak psi lhr
paulirish Jul 21, 2021
a769ffc
revert generateReportHTML changes
paulirish Jul 23, 2021
a65420a
cli flag and other feedback
paulirish Jul 23, 2021
67d9565
move files to test-assets
paulirish Jul 23, 2021
7a1c42b
address remaining feedback
paulirish Jul 23, 2021
b971fb3
adjust build report cmds from feedback
paulirish Aug 3, 2021
e0c958e
Merge remote-tracking branch 'origin/master' into faux-psi
paulirish Aug 3, 2021
0cab294
type-check fixes
paulirish Aug 3, 2021
1364af2
lint
paulirish Aug 3, 2021
51d832b
PrepareLabDataResult
paulirish Aug 3, 2021
ffa6ec3
flags and logs
paulirish Aug 3, 2021
0dc332f
rm watch:report
paulirish Aug 10, 2021
3d02808
brendan's feedback
paulirish Aug 10, 2021
2474bd4
Merge remote-tracking branch 'origin/master' into faux-psi
paulirish Aug 10, 2021
bcdc3d8
Merge remote-tracking branch 'origin/master' into faux-psi
paulirish Aug 11, 2021
21fcf51
Merge remote-tracking branch 'origin/master' into faux-psi
paulirish Aug 11, 2021
77a488d
remove references to LIGHTHOUSE_TEMPLATES as templates.html aint a th…
paulirish Aug 11, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions build/build-report.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,25 @@ async function buildUmdBundle() {
}

if (require.main === module) {
if (process.argv[2] === '--only-standalone') {
buildStandaloneReport();
} else {
if (process.argv.length <= 2) {
buildStandaloneReport();
buildEsModulesBundle();
buildPsiReport();
buildUmdBundle();
}

if (process.argv.includes('--psi')) {
buildPsiReport();
}
if (process.argv.includes('--standalone')) {
buildStandaloneReport();
}
if (process.argv.includes('--esm')) {
buildEsModulesBundle();
}
if (process.argv.includes('--umd')) {
buildUmdBundle();
}
}

module.exports = {
Expand Down
50 changes: 47 additions & 3 deletions lighthouse-core/scripts/build-report-for-autodeployment.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const {defaultSettings} = require('../config/constants.js');
const lighthouse = require('../index.js');
const lhr = /** @type {LH.Result} */ (require('../../lighthouse-core/test/results/sample_v2.json'));
const {LH_ROOT} = require('../../root.js');
const htmlReportAssets = require('../../report/report-assets.js');


const DIST = path.join(LH_ROOT, `dist/now`);

Expand All @@ -29,19 +31,23 @@ const DIST = path.join(LH_ROOT, `dist/now`);
'ɑrabic': swapLocale(lhr, 'ar').lhr,
'xl-accented': swapLocale(lhr, 'en-XL').lhr,
'error': errorLhr,
'single-category': tweakLhrForPsi(lhr),
};

// Generate and write reports
Object.entries(filenameToLhr).forEach(([filename, lhr]) => {
let html = ReportGenerator.generateReportHtml(lhr);
// TODO: PSI is another variant to consider
for (const variant of ['', '⌣.cdt.']) {
for (const variant of ['', '⌣.cdt.', '⌣.psi.']) {
let html = variant.includes('psi') ?
generatePsiReportHtml() :
ReportGenerator.generateReportHtml(lhr);

if (variant.includes('cdt')) {
// TODO: Make the DevTools Audits panel "emulation" more comprehensive
// - the parent widget/vbox container with overflow
// - a more constrained/realistic default size
html = html.replace(`"lh-root lh-vars"`, `"lh-root lh-vars lh-devtools"`);
}

const filepath = `${DIST}/${variant}${filename}/index.html`;
fs.mkdirSync(path.dirname(filepath), {recursive: true});
fs.writeFileSync(filepath, html, {encoding: 'utf-8'});
Expand All @@ -50,6 +56,26 @@ const DIST = path.join(LH_ROOT, `dist/now`);
});
})();


/**
* @return {string}
*/
function generatePsiReportHtml() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this definitely seems kind of weird in build-report-for-autodeployment.js and possibly hard to keep up to date when changes happen to report-generator, but I also like keeping it simple like this while we iterate on report/overall build story

const sanitizedJson = ReportGenerator.sanitizeJson(tweakLhrForPsi(lhr));
const PSI_TEMPLATE = fs.readFileSync(
`${LH_ROOT}/report/test-assets/faux-psi-template.html`, 'utf8');
const PSI_JAVASCRIPT = `
${fs.readFileSync(`${LH_ROOT}/dist/report/psi.js`, 'utf8')};
${fs.readFileSync(`${LH_ROOT}/report/test-assets/faux-psi.js`, 'utf8')};
`;

const html = ReportGenerator.replaceStrings(PSI_TEMPLATE, [
{search: '%%LIGHTHOUSE_JSON%%', replacement: sanitizedJson},
{search: '%%LIGHTHOUSE_JAVASCRIPT%%', replacement: PSI_JAVASCRIPT},
{search: '/*%%LIGHTHOUSE_CSS%%*/', replacement: htmlReportAssets.REPORT_CSS},
]);
return html;
}
/**
* Add a plugin to demo plugin rendering.
* @param {LH.Result} lhr
Expand All @@ -63,6 +89,24 @@ function addPluginCategory(lhr) {
};
}

/**
* Drops the LHR to only one, solo category (performance), and removes budgets.
* @param {LH.Result} lhr
*/
function tweakLhrForPsi(lhr) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this matter? Shouldn't it just be able to take a regular LHR and just ignore the stuff it doesn't want? Or is this more a matter of giving it the data it will actually get in practice for a more realistic deployment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldnt matter much, but I just wanted to the data to match what PSI would expect to see. I can't think of any real reasons why it'd matter (like full-page-screenshot being in another category or something).

/** @type {LH.Result} */
const clone = JSON.parse(JSON.stringify(lhr));
clone.categories = {
'performance': clone.categories.performance,
};
// no budgets in PSI
delete clone.audits['performance-budget'];
clone.categories.performance.auditRefs = clone.categories.performance.auditRefs.filter(audit => {
return !audit.id.endsWith('-budget');
});
return clone;
}

/**
* Generate an LHR with errors for the renderer to display.
* We'll write an "empty" artifacts file to disk, only to use it in auditMode.
Expand Down
1 change: 0 additions & 1 deletion lighthouse-viewer/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
<link rel="stylesheet" href="styles/bundled.css">
</head>
<body class="lh-root lh-vars">
<div hidden>%%LIGHTHOUSE_TEMPLATES%%</div>

<div class="drop_zone"></div>

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"build-lr": "yarn reset-link && node ./build/build-lightrider-bundles.js",
"build-pack": "bash build/build-pack.sh",
"build-report": "node build/build-report-components.js && yarn eslint --fix report/renderer/components.js && node build/build-report.js",
"build-dist-reports": "yarn build-report && node lighthouse-core/scripts/build-report-for-autodeployment.js",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bike shed: what is build-dist-reports referring to? Just build reports that will be in dist/? Because it's also sample reports in particular. build-sample-reports?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hehe me and paul were talking about the naming here...

  • build-dist-reports: Builds the report renderer and the reports for the Vercel deployment
  • build-report-for-autodeployment.js: Builds the reports for the Vercel deployment
  • now-build: The Vercel deployment used to be called "now". not anymore

some renaming is in order all around.

"build-treemap": "node ./build/build-treemap.js",
"build-viewer": "node ./build/build-viewer.js",
"reset-link": "(yarn unlink || true) && yarn link && yarn link lighthouse",
Expand All @@ -32,7 +33,7 @@
"lint": "[ \"$CI\" = true ] && eslint --quiet -f codeframe . || eslint .",
"smoke": "node lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js",
"debug": "node --inspect-brk ./lighthouse-cli/index.js",
"start": "yarn build-report --only-standalone && node ./lighthouse-cli/index.js",
"start": "yarn build-report --standalone && node ./lighthouse-cli/index.js",
"jest": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js",
"test": "yarn diff:sample-json && yarn lint --quiet && yarn unit && yarn type-check",
"test-bundle": "yarn smoke --runner bundle -j=1 --retries=2 --invert-match forms",
Expand Down Expand Up @@ -62,7 +63,7 @@
"fast": "node ./lighthouse-cli/index.js --preset=desktop --throttlingMethod=provided",
"deploy-treemap": "yarn build-treemap --deploy",
"deploy-viewer": "yarn build-viewer --deploy",
"now-build": "yarn build-report && node lighthouse-core/scripts/build-report-for-autodeployment.js && yarn build-viewer && yarn build-treemap && cp -r dist/gh-pages dist/now/gh-pages",
"now-build": "yarn build-dist-reports && yarn build-viewer && yarn build-treemap && cp -r dist/gh-pages dist/now/gh-pages",
"dogfood-lhci": "./lighthouse-core/scripts/dogfood-lhci.sh",
"timing-trace": "node lighthouse-core/scripts/generate-timing-trace.js",
"changelog": "conventional-changelog --config ./build/changelog-generator/index.js --infile changelog.md --same-file",
Expand Down
1 change: 0 additions & 1 deletion report/assets/standalone-template.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
</head>
<body class="lh-root lh-vars">
<noscript>Lighthouse report requires JavaScript. Please enable.</noscript>
<div hidden>%%LIGHTHOUSE_TEMPLATES%%</div>

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

Expand Down
15 changes: 13 additions & 2 deletions report/clients/psi.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import {PerformanceCategoryRenderer} from '../renderer/performance-category-rend
import {ReportUIFeatures} from '../renderer/report-ui-features.js';
import {Util} from '../renderer/util.js';

/* global window */

/** @typedef {{scoreGaugeEl: Element, perfCategoryEl: Element, finalScreenshotDataUri: string|null, scoreScaleEl: Element, installFeatures: Function}} PrepareLabDataResult */

/**
* Returns all the elements that PSI needs to render the report
* We expose this helper method to minimize the 'public' API surface of the renderer
Expand All @@ -36,7 +40,7 @@ import {Util} from '../renderer/util.js';
*
* @param {LH.Result | string} LHResult The stringified version of {LH.Result}
* @param {Document} document The host page's window.document
* @return {{scoreGaugeEl: Element, perfCategoryEl: Element, finalScreenshotDataUri: string|null, scoreScaleEl: Element, installFeatures: Function}}
* @return {PrepareLabDataResult}
*/
export function prepareLabData(LHResult, document) {
const lhResult = (typeof LHResult === 'string') ?
Expand Down Expand Up @@ -89,10 +93,11 @@ export function prepareLabData(LHResult, document) {
/** @param {HTMLElement} reportEl */
const installFeatures = (reportEl) => {
if (fullPageScreenshot) {
// 1) Add fpss css var to reportEl parent so any thumbnails will work
ElementScreenshotRenderer.installFullPageScreenshot(
reportEl, fullPageScreenshot.screenshot);

// Append the overlay element to a specific part of the DOM so that
// 2) Append the overlay element to a specific part of the DOM so that
// the sticky tab group element renders correctly. If put in the reportEl
// like normal, then the sticky header would bleed through the overlay
// element.
Expand Down Expand Up @@ -141,3 +146,9 @@ function _getFinalScreenshot(perfCategory) {
if (!details || details.type !== 'screenshot') return null;
return details.data;
}

// TODO: remove with report API refactor.
if (typeof window !== 'undefined') {
// @ts-expect-error
window.prepareLabData = prepareLabData;
}
18 changes: 13 additions & 5 deletions report/report-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,23 @@ class ReportGenerator {
}

/**
* Returns the report HTML as a string with the report JSON and renderer JS inlined.
* @param {unknown} object
* @return {string}
*/
static sanitizeJson(object) {
return JSON.stringify(object)
.replace(/</g, '\\u003c') // replaces opening script tags
.replace(/\u2028/g, '\\u2028') // replaces line separators ()
.replace(/\u2029/g, '\\u2029'); // replaces paragraph separators
}

/**
* Returns the standalone report HTML as a string with the report JSON and renderer JS inlined.
* @param {LH.Result} lhr
* @return {string}
*/
static generateReportHtml(lhr) {
const sanitizedJson = JSON.stringify(lhr)
.replace(/</g, '\\u003c') // replaces opening script tags
.replace(/\u2028/g, '\\u2028') // replaces line separators ()
.replace(/\u2029/g, '\\u2029'); // replaces paragraph separators
const sanitizedJson = ReportGenerator.sanitizeJson(lhr);
// terser does its own sanitization, but keep this basic replace for when
// we want to generate a report without minification.
const sanitizedJavascript = htmlReportAssets.REPORT_JAVASCRIPT.replace(/<\//g, '\\u003c/');
Expand Down
126 changes: 126 additions & 0 deletions report/test-assets/faux-psi-template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<!--
* 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.
-->

<!--
This fake psi page is intended to reproduce the experience of rendering two LHRs within the same DOM,
like in PageSpeed Insights. This helps surface the peculiar behavior around tabs,
expectations of unique IDs, and scoped report containment.
-->

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<title>Faux PageSpeed Report</title>
<style>/*%%LIGHTHOUSE_CSS%%*/</style>

<style>
/* Inspired by https://codepen.io/markcaron/pen/MvGRYV?editors=1100 but improved. s*/
/*
The tab visibility basics
*/
.tabset > input[type="radio"] {
position: absolute;
left: -200vw;
}

.tabset .tab-panel {
display: none;
}

.tabset > input:nth-of-type(1):checked ~ .tab-panels > .tab-panel:nth-of-type(1),
.tabset > input:nth-of-type(2):checked ~ .tab-panels > .tab-panel:nth-of-type(2) {
display: block;
}

/*
Purdy tabs
*/
.tabset > label {
position: relative;
display: inline-block;
padding: 15px 55px 15px;
border: 1px solid transparent;
border-bottom: 0;
cursor: pointer;
font-weight: 600;
}

.tabset > label:hover {
background-color: hsl(0deg 0% 100% / 24%);
}

.tabset > label:hover,
.tabset > input:focus + label {
color: #06c;
}

.tabset > input:checked + label {
border-color: #ccc;
border-bottom: 1px solid #fff;
margin-bottom: -1px;
background: white;
}

.tab-panel {
padding: 30px 0;
border-top: 1px solid #ccc;
}

body {
padding: 30px;
}

.tabset {
max-width: 65em;
background: #eee;
}

.tab-panels {
background: white;
}

/* extra styles */
body {
background: hsl(217deg 89% 61%);
}
</style>
</head>
<body >
<noscript>PSI requires JavaScript. Please enable.</noscript>

<div class="element-screenshots-container"></div>


<div class="tabset lh-vars lh-root">

<input type="radio" name="tabset" id="tab1" aria-controls="mobile" checked>
<label for="tab1">Mobile</label>

<input type="radio" name="tabset" id="tab2" aria-controls="desktop">
<label for="tab2">Desktop</label>

<div class="tab-panels">
<section id="mobile" class="tab-panel">
<main></main>
</section>

<section id="desktop" class="tab-panel">
<main></main>
</section>

</div>
</div>

<script>window.__LIGHTHOUSE_JSON__ = %%LIGHTHOUSE_JSON%%;</script>
<script type="module">
%%LIGHTHOUSE_JAVASCRIPT%%
//# sourceURL=psi-reportrenderer.js
</script>
<script>console.log('window.__LIGHTHOUSE_JSON__', __LIGHTHOUSE_JSON__);</script>
</body>
</html>
Loading