Skip to content

core: record top-level warnings in LHR and display in report#3692

Merged
paulirish merged 6 commits intomasterfrom
squirrelly
Oct 31, 2017
Merged

core: record top-level warnings in LHR and display in report#3692
paulirish merged 6 commits intomasterfrom
squirrelly

Conversation

@brendankenny
Copy link
Contributor

@brendankenny brendankenny commented Oct 30, 2017

Adds a LighthouseRunWarnings artifact in gather-runner and a lighthouseRunWarnings in runner (which LighthouseRunWarnings is folded into when gather-runner is complete) to collect top-level warnings worthy of bringing to the user's attention (e.g. ran in Headless which doesn't support throttling). For now only gather-runner and runner can add to these, but should be easy to extend if we want to e.g. let gatherers or audits emit warnings they think are worthy of floating to the top. Happy to bikeshed on naming and exact flow of warning strings.

steals the styling in the HTML report from #2920, but not remotely attached to it :)

screen shot 2017-10-30 at 15 52 23

closes #2920 by adding a warning when running in Headless

const artifacts = {};

// Nest LighthouseRunWarnings, if any, so they will be collected into artifact.
gathererResults.LighthouseRunWarnings = [gathererResults.LighthouseRunWarnings || []];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this ends up a bit weird. gatherResults expects an array of results for [beforePass, pass, afterPass] , the winner of which is selected just below. For adding warnings, however, that means everywhere a warning is added would have to do gathererResults.LighthouseRunWarnings[0].push('...'). This cheats it by keeping gathererResults.LighthouseRunWarnings a top level array everywhere (so it's just gathererResults.LighthouseRunWarnings.push('...')) and then nesting it into an array so it can be processed here

* @return {?DocumentFragment}
*/
_renderReportWarnings(report) {
if (!report.lighthouseRunWarnings || report.lighthouseRunWarnings.length === 0) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

alternatively this could return an empty div so the caller wouldn't need to check the results

Copy link
Collaborator

Choose a reason for hiding this comment

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

I suppose I have a slight preference for empty div, but I don't feel terribly strongly if this is a pattern we can expect to employ elsewhere as well (I can't think of any off the top of my head, but maybe you borrowed from somewhere?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have a slight preference for empty div

done

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

hurray finally a mechanism for top level warnings! :D

what do the expected flows look like for adding items to the warnings from audits and gatherers?

from audits: depend on the RunWarnings artifact and mutate it? feels a bit gross but super easy
from gatherers: add runWarnings to passData and give to gatherer afterPass?

const artifacts = {};

// Nest LighthouseRunWarnings, if any, so they will be collected into artifact.
gathererResults.LighthouseRunWarnings = [gathererResults.LighthouseRunWarnings || []];
Copy link
Collaborator

Choose a reason for hiding this comment

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

shouldn't gathererResults.LighthouseRunWarnings always be set? if not, do we need a safeguard in warnOnHeadless too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

shouldn't gathererResults.LighthouseRunWarnings always be set?

it should always be set, I was thinking of runner when I added that :)

* timing: {total: number},
* initialUrl: string,
* url: string,
* lighthouseRunWarnings: !Array<string>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

not sure how we should be modeling extensions to the report JSON here, the latest renderer needs to render older versions that might be missing runWarnings, which you account for, but it is nice to have the closure annotations match the current invariants

thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, it should be optional. Fixed

generatedTime: (new Date()).toJSON(),
initialUrl: opts.initialUrl,
url: opts.url,
lighthouseRunWarnings,
Copy link
Collaborator

Choose a reason for hiding this comment

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

🚲 🏠 can we ditch the lighthouse prefix, it's the LHR so hopefully everything is lighthouse related

don't want to end up in a classic lighthouse-core, lighthouse-cli, lighthouse-* situation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SG

line-height: var(--header-line-height);
}
.lh-run-warnings::before {
display: inline-block;
Copy link
Collaborator

Choose a reason for hiding this comment

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

interesting, what for? oh are you reusing an icon from some other class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh are you reusing an icon from some other class?

yeah, the styling from lh-debug. Stolen from Eric's #2920

* @return {?DocumentFragment}
*/
_renderReportWarnings(report) {
if (!report.lighthouseRunWarnings || report.lighthouseRunWarnings.length === 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suppose I have a slight preference for empty div, but I don't feel terribly strongly if this is a pattern we can expect to employ elsewhere as well (I can't think of any off the top of my head, but maybe you borrowed from somewhere?)

* @param {!Driver} driver
* @param {!GathererResults} gathererResults
* @return {!Promise<undefined>}
*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: we just computed UserAgent the step before this, so could eliminate driver dep

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@brendankenny
Copy link
Contributor Author

what do the expected flows look like for adding items to the warnings from audits and gatherers?

I actually hadn't thought about gatherers hard enough. passData might make sense, though it's somewhat unfortunate for beforePass and pass not to have access. Not sure of other methods to get data out of a gatherer.

I was thinking the LighthouseRunWarnings artifact should be immutable after gathering is finished, which would allow GAR to recreate warnings correctly, for instance. Audits could just have yet another field in AuditResult to issue top-level warnings (hopefully rarely) and merged within runner to its local copy, not the artifact.

A separate idea from all of this would be some new logger method which would allow it to be stored somewhere. Runner could start and then stop recording, and append any collected super logs into runWarnings. This is nice since logger is already global and a singleton and we don't need yet another injected thing, and it is a kind of logging, but OTOH it's not reentrant and kind of ugly, so I decided to not pursue.

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

lgtm!

<!-- Lighthouse run warnings -->
<template id="tmpl-lh-run-warnings">
<div class="lh-run-warnings lh-debug">
<b>There were issues affecting this run of Lighthouse:</b>
Copy link
Collaborator

Choose a reason for hiding this comment

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

is strong not the hip young tag it once was? 😆

Copy link

@vinamratasingal-zz vinamratasingal-zz left a comment

Choose a reason for hiding this comment

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

Brendan- small nit on UX. Can we make the error section of the report a box with a light yellow background? This will help separate the content out for end user. I also think having it red font makes it a bit scary, so changing it to a non-red color would be helpful. I can throw together a quick mock if that's useful.

Also- what's the product behavior with surfacing errors. How many errors can surface at a time, is there anyway that we can help prioritize, and do we want to have an opinion on how many errors to flash/what gets shown here?

@brendankenny
Copy link
Contributor Author

updated styling:
screen shot 2017-10-30 at 15 52 23

Copy link

@vinamratasingal-zz vinamratasingal-zz left a comment

Choose a reason for hiding this comment

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

LGTM, thanks Brendan!

@brendankenny
Copy link
Contributor Author

@paulirish if you want in

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants