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

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

Merged
merged 6 commits into from
Oct 31, 2017

Conversation

brendankenny
Copy link
Member

@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

@@ -301,6 +319,9 @@ class GatherRunner {
static collectArtifacts(gathererResults) {
const artifacts = {};

// Nest LighthouseRunWarnings, if any, so they will be collected into artifact.
gathererResults.LighthouseRunWarnings = [gathererResults.LighthouseRunWarnings || []];
Copy link
Member 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

*/
_renderReportWarnings(report) {
if (!report.lighthouseRunWarnings || report.lighthouseRunWarnings.length === 0) {
return null;
Copy link
Member 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
Member 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?

@@ -301,6 +319,9 @@ class GatherRunner {
static collectArtifacts(gathererResults) {
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
Member 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 :)

@@ -202,6 +227,7 @@ ReportRenderer.GroupJSON; // eslint-disable-line no-unused-expressions
* 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
Member 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

@@ -150,6 +157,7 @@ class Runner {
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
Member 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
Member 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

*/
_renderReportWarnings(report) {
if (!report.lighthouseRunWarnings || report.lighthouseRunWarnings.length === 0) {
return null;
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 {!GathererResults} gathererResults
* @return {!Promise<undefined>}
*/
static warnOnHeadless(driver, gathererResults) {
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
Member 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
Member 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
Member 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
Member 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