From dcb5e1978e55a3028f7f465ee8b497e2875cac05 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Mon, 28 Dec 2020 19:28:07 -0600 Subject: [PATCH 1/8] core(console-messages): use source-location --- lighthouse-core/audits/deprecations.js | 22 +++-------------- .../dobetterweb/geolocation-on-start.js | 3 +-- .../audits/dobetterweb/no-document-write.js | 3 +-- .../dobetterweb/notification-on-start.js | 3 +-- .../uses-passive-event-listeners.js | 3 +-- lighthouse-core/audits/errors-in-console.js | 6 ++--- lighthouse-core/audits/no-unload-listeners.js | 2 +- lighthouse-core/audits/violation-audit.js | 24 ++++++++++++++----- .../gather/gatherers/console-messages.js | 24 +++++++++++++++++++ types/artifacts.d.ts | 4 ++-- 10 files changed, 55 insertions(+), 39 deletions(-) diff --git a/lighthouse-core/audits/deprecations.js b/lighthouse-core/audits/deprecations.js index 3c3889145c94..8c270829f929 100644 --- a/lighthouse-core/audits/deprecations.js +++ b/lighthouse-core/audits/deprecations.js @@ -13,6 +13,7 @@ const Audit = require('./audit.js'); const i18n = require('../lib/i18n/i18n.js'); +const ConsoleMessages = require('../gather/gatherers/console-messages.js'); const UIStrings = { /** Title of a Lighthouse audit that provides detail on the use of deprecated APIs. This descriptive title is shown to users when the page does not use deprecated APIs. */ @@ -57,33 +58,16 @@ class Deprecations extends Audit { const entries = artifacts.ConsoleMessages; const deprecations = entries.filter(log => log.source === 'deprecation').map(log => { - // HTML deprecations will have no url and no way to attribute to a specific line. - /** @type {LH.Audit.Details.SourceLocationValue=} */ - let source; - if (log.url) { - // JS deprecations will have a stack trace. - // CSS deprecations only expose a line number. - const topCallFrame = log.stackTrace && log.stackTrace.callFrames[0]; - const line = log.lineNumber || 0; - const column = topCallFrame ? topCallFrame.columnNumber : 0; - source = { - type: 'source-location', - url: log.url, - urlProvider: 'network', - line, - column, - }; - } return { value: log.text, - source, + source: ConsoleMessages.createSourceLocation(log), }; }); /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ {key: 'value', itemType: 'text', text: str_(UIStrings.columnDeprecate)}, - {key: 'source', itemType: 'source-location', text: str_(i18n.UIStrings.columnURL)}, + {key: 'source', itemType: 'source-location', text: str_(i18n.UIStrings.columnSource)}, ]; const details = Audit.makeTableDetails(headings, deprecations); diff --git a/lighthouse-core/audits/dobetterweb/geolocation-on-start.js b/lighthouse-core/audits/dobetterweb/geolocation-on-start.js index 9fb35e3ee1cb..ba3a3b0e3ffd 100644 --- a/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +++ b/lighthouse-core/audits/dobetterweb/geolocation-on-start.js @@ -51,8 +51,7 @@ class GeolocationOnStart extends ViolationAudit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)}, - {key: 'label', itemType: 'text', text: str_(i18n.UIStrings.columnLocation)}, + {key: 'source', itemType: 'source-location', text: str_(i18n.UIStrings.columnSource)}, ]; // TODO(bckenny): there should actually be a ts error here. results[0].stackTrace // should violate the results type. Shouldn't be removed from details items regardless. diff --git a/lighthouse-core/audits/dobetterweb/no-document-write.js b/lighthouse-core/audits/dobetterweb/no-document-write.js index 90cd0f0069fc..36190e6c6890 100644 --- a/lighthouse-core/audits/dobetterweb/no-document-write.js +++ b/lighthouse-core/audits/dobetterweb/no-document-write.js @@ -67,8 +67,7 @@ class NoDocWriteAudit extends ViolationAudit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)}, - {key: 'label', itemType: 'text', text: str_(i18n.UIStrings.columnLocation)}, + {key: 'source', itemType: 'source-location', text: str_(i18n.UIStrings.columnSource)}, ]; // TODO(bckenny): see TODO in geolocation-on-start const details = ViolationAudit.makeTableDetails(headings, results); diff --git a/lighthouse-core/audits/dobetterweb/notification-on-start.js b/lighthouse-core/audits/dobetterweb/notification-on-start.js index ec008645cce4..7f32402ac054 100644 --- a/lighthouse-core/audits/dobetterweb/notification-on-start.js +++ b/lighthouse-core/audits/dobetterweb/notification-on-start.js @@ -50,8 +50,7 @@ class NotificationOnStart extends ViolationAudit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)}, - {key: 'label', itemType: 'text', text: str_(i18n.UIStrings.columnLocation)}, + {key: 'source', itemType: 'source-location', text: str_(i18n.UIStrings.columnSource)}, ]; // TODO(bckenny): see TODO in geolocation-on-start const details = ViolationAudit.makeTableDetails(headings, results); diff --git a/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js b/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js index db83a8b0a78f..c5fe2a07c7b6 100644 --- a/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js +++ b/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js @@ -50,8 +50,7 @@ class PassiveEventsAudit extends ViolationAudit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)}, - {key: 'label', itemType: 'text', text: str_(i18n.UIStrings.columnLocation)}, + {key: 'source', itemType: 'source-location', text: str_(i18n.UIStrings.columnSource)}, ]; // TODO(bckenny): see TODO in geolocation-on-start const details = ViolationAudit.makeTableDetails(headings, results); diff --git a/lighthouse-core/audits/errors-in-console.js b/lighthouse-core/audits/errors-in-console.js index 6ae4d4bcdd51..0be93fdb0bc2 100644 --- a/lighthouse-core/audits/errors-in-console.js +++ b/lighthouse-core/audits/errors-in-console.js @@ -13,6 +13,7 @@ const log = require('lighthouse-logger'); const Audit = require('./audit.js'); const i18n = require('../lib/i18n/i18n.js'); +const ConsoleMessages = require('../gather/gatherers/console-messages.js'); const UIStrings = { /** Title of a Lighthouse audit that provides detail on browser errors. This descriptive title is shown to users when no browser errors were logged into the devtools console. */ @@ -48,7 +49,6 @@ class ErrorLogs extends Audit { return {}; } - /** * @template {{description: string | undefined}} T * @param {Array} items @@ -81,14 +81,14 @@ class ErrorLogs extends Audit { /** @type {AuditOptions} */ const auditOptions = context.options; - /** @type {Array<{source: string, description: string|undefined, url: string|undefined}>} */ + /** @type {Array<{source: string, description: string|undefined, sourceLocation: LH.Audit.Details.SourceLocationValue|undefined}>} */ const consoleRows = artifacts.ConsoleMessages .filter(item => item.level === 'error') .map(item => { return { source: item.source, description: item.text, - url: item.url, + sourceLocation: ConsoleMessages.createSourceLocation(item), }; }); diff --git a/lighthouse-core/audits/no-unload-listeners.js b/lighthouse-core/audits/no-unload-listeners.js index d8c7adf0f8cf..7d53c8345b00 100644 --- a/lighthouse-core/audits/no-unload-listeners.js +++ b/lighthouse-core/audits/no-unload-listeners.js @@ -47,7 +47,7 @@ class NoUnloadListeners extends Audit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'source', itemType: 'source-location', text: str_(i18n.UIStrings.columnURL)}, + {key: 'source', itemType: 'source-location', text: str_(i18n.UIStrings.columnSource)}, ]; // Look up scriptId to script URL via the JsUsage artifact. diff --git a/lighthouse-core/audits/violation-audit.js b/lighthouse-core/audits/violation-audit.js index ee52285dbe5e..5f058cab7542 100644 --- a/lighthouse-core/audits/violation-audit.js +++ b/lighthouse-core/audits/violation-audit.js @@ -6,26 +6,38 @@ 'use strict'; const Audit = require('./audit.js'); +const ConsoleMessages = require('../gather/gatherers/console-messages.js'); class ViolationAudit extends Audit { /** * @param {LH.Artifacts} artifacts * @param {RegExp} pattern - * @return {Array<{label: string, url?: string}>} + * @return {Array<{source: LH.Audit.Details.SourceLocationValue}>} */ static getViolationResults(artifacts, pattern) { + /** + * @template T + * @param {T} value + * @return {value is Exclude} + */ + function filterUndefined(value) { + return value !== undefined; + } + const seen = new Set(); return artifacts.ConsoleMessages .filter(entry => entry.url && entry.source === 'violation' && pattern.test(entry.text)) - .map(entry => ({label: `line: ${entry.lineNumber}`, url: entry.url})) - .filter(entry => { - // Filter out duplicate entries by URL/label since they are not differentiable to the user + .map(entry => ConsoleMessages.createSourceLocation(entry)) + .filter(filterUndefined) + .filter(source => { + // Filter out duplicate entries since they are not differentiable to the user // @see https://github.com/GoogleChrome/lighthouse/issues/5218 - const key = `${entry.url}!${entry.label}`; + const key = `${source.url}!${source.line}!${source.column}`; if (seen.has(key)) return false; seen.add(key); return true; - }); + }) + .map(source => ({source})); } } diff --git a/lighthouse-core/gather/gatherers/console-messages.js b/lighthouse-core/gather/gatherers/console-messages.js index 79c4b29fcf88..87ac36178bac 100644 --- a/lighthouse-core/gather/gatherers/console-messages.js +++ b/lighthouse-core/gather/gatherers/console-messages.js @@ -31,6 +31,22 @@ function remoteObjectToString(obj) { } class ConsoleMessages extends Gatherer { + /** + * @param {LH.Artifacts.ConsoleMessage} entry + * @return {LH.Audit.Details.SourceLocationValue | undefined} + */ + static createSourceLocation(entry) { + if (!entry.url) return; + + return { + type: 'source-location', + url: entry.url, + urlProvider: 'network', + line: entry.lineNumber || 0, + column: entry.columnNumber || 0, + }; + } + constructor() { super(); /** @type {LH.Artifacts.ConsoleMessage[]} */ @@ -51,6 +67,7 @@ class ConsoleMessages extends Gatherer { // Only gather warnings and errors for brevity. return; } + /** @type {LH.Crdp.Runtime.RemoteObject[]} */ const args = event.args || []; const text = args.map(remoteObjectToString).join(' '); @@ -58,6 +75,7 @@ class ConsoleMessages extends Gatherer { // No useful information from Chrome. Skip. return; } + const {url, lineNumber, columnNumber} = event.stackTrace && event.stackTrace.callFrames[0] || {}; /** @type {LH.Artifacts.ConsoleMessage} */ @@ -107,6 +125,11 @@ class ConsoleMessages extends Gatherer { */ onLogEntry(event) { const {source, level, text, stackTrace, timestamp, url, lineNumber} = event.entry; + + // JS events have a stack trace, which we use to get the column. + // CSS/HTML events only expose a line number. + const {columnNumber} = event.entry.stackTrace && event.entry.stackTrace.callFrames[0] || {}; + this._logEntries.push({ eventType: 'protocolLog', source, @@ -116,6 +139,7 @@ class ConsoleMessages extends Gatherer { timestamp, url, lineNumber, + columnNumber, }); } diff --git a/types/artifacts.d.ts b/types/artifacts.d.ts index 6350a3e6281d..e28b5feaa881 100644 --- a/types/artifacts.d.ts +++ b/types/artifacts.d.ts @@ -773,9 +773,9 @@ declare global { stackTrace?: Crdp.Runtime.StackTrace; /** The URL of the log/exception, if known. */ url?: string; - /** Line number in the script (0-based), if known. */ + /** Line number in the script (0-indexed), if known. */ lineNumber?: number; - /** Column number in the script (0-based), if known. */ + /** Column number in the script (0-indexed), if known. */ columnNumber?: number; } From 9c00d4b0d0c1dba6275bf3a2290abd2f66978e8a Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Mon, 28 Dec 2020 19:33:17 -0600 Subject: [PATCH 2/8] tweak --- lighthouse-core/audits/errors-in-console.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lighthouse-core/audits/errors-in-console.js b/lighthouse-core/audits/errors-in-console.js index 0be93fdb0bc2..0e44c45c1072 100644 --- a/lighthouse-core/audits/errors-in-console.js +++ b/lighthouse-core/audits/errors-in-console.js @@ -97,7 +97,7 @@ class ErrorLogs extends Audit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)}, + {key: 'sourceLocation', itemType: 'source-location', text: str_(i18n.UIStrings.columnSource)}, {key: 'description', itemType: 'code', text: str_(i18n.UIStrings.columnDescription)}, ]; From 6d562bbdb56a4a16fd3f5cfbd975076cc746c322 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Mon, 28 Dec 2020 19:41:33 -0600 Subject: [PATCH 3/8] fixtest --- lighthouse-core/audits/errors-in-console.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lighthouse-core/audits/errors-in-console.js b/lighthouse-core/audits/errors-in-console.js index 0e44c45c1072..c770b872e450 100644 --- a/lighthouse-core/audits/errors-in-console.js +++ b/lighthouse-core/audits/errors-in-console.js @@ -88,6 +88,7 @@ class ErrorLogs extends Audit { return { source: item.source, description: item.text, + url: item.url, sourceLocation: ConsoleMessages.createSourceLocation(item), }; }); From 28cd4c8ed5f3a03befdbf02c37c80cfb750ea046 Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Tue, 29 Dec 2020 13:34:09 -0600 Subject: [PATCH 4/8] update --- lighthouse-core/test/results/sample_v2.json | 243 +++++++++++++------- 1 file changed, 154 insertions(+), 89 deletions(-) diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index 1e223f6aeba3..e6712d7bc881 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -239,9 +239,9 @@ "type": "table", "headings": [ { - "key": "url", - "itemType": "url", - "text": "URL" + "key": "sourceLocation", + "itemType": "source-location", + "text": "Source" }, { "key": "description", @@ -253,42 +253,98 @@ { "source": "other", "description": "Application Cache Error event: Manifest fetch failed (404) http://localhost:10200/dobetterweb/clock.appcache", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "sourceLocation": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 0, + "column": 0 + } }, { "source": "exception", "description": "Error: A distinctive error\n at http://localhost:10200/dobetterweb/dbw_tester.html:58:54", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "sourceLocation": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 57, + "column": 53 + } }, { "source": "exception", "description": "Error: An ignored error\n at http://localhost:10200/dobetterweb/dbw_tester.html:61:38", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "sourceLocation": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 60, + "column": 37 + } }, { "source": "console.error", "description": "Error! Error!", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "sourceLocation": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 474, + "column": 10 + } }, { "source": "network", "description": "Failed to load resource: the server responded with a status of 404 (Not Found)", - "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200" + "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200", + "sourceLocation": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200", + "urlProvider": "network", + "line": 0, + "column": 0 + } }, { "source": "network", "description": "Failed to load resource: the server responded with a status of 404 (Not Found)", - "url": "http://localhost:10200/dobetterweb/fcp-delayer.js?delay=5000" + "url": "http://localhost:10200/dobetterweb/fcp-delayer.js?delay=5000", + "sourceLocation": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/fcp-delayer.js?delay=5000", + "urlProvider": "network", + "line": 0, + "column": 0 + } }, { "source": "network", "description": "Failed to load resource: the server responded with a status of 404 (Not Found)", - "url": "http://localhost:10200/favicon.ico" + "url": "http://localhost:10200/favicon.ico", + "sourceLocation": { + "type": "source-location", + "url": "http://localhost:10200/favicon.ico", + "urlProvider": "network", + "line": 0, + "column": 0 + } }, { "source": "network", "description": "Failed to load resource: the server responded with a status of 404 (Not Found)", - "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200" + "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200", + "sourceLocation": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200", + "urlProvider": "network", + "line": 0, + "column": 0 + } } ] } @@ -742,7 +798,7 @@ { "key": "source", "itemType": "source-location", - "text": "URL" + "text": "Source" } ], "items": [ @@ -763,7 +819,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.js", "urlProvider": "network", "line": 13, - "column": 9 + "column": 0 } }, { @@ -773,7 +829,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "urlProvider": "network", "line": 371, - "column": 6 + "column": 0 } }, { @@ -1984,7 +2040,7 @@ { "key": "source", "itemType": "source-location", - "text": "URL" + "text": "Source" } ], "items": [ @@ -4169,24 +4225,29 @@ "type": "table", "headings": [ { - "key": "url", - "itemType": "url", - "text": "URL" - }, - { - "key": "label", - "itemType": "text", - "text": "Location" + "key": "source", + "itemType": "source-location", + "text": "Source" } ], "items": [ { - "label": "line: 331", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "source": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 331, + "column": 0 + } }, { - "label": "line: 335", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "source": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 335, + "column": 0 + } } ] } @@ -4209,28 +4270,38 @@ "type": "table", "headings": [ { - "key": "url", - "itemType": "url", - "text": "URL" - }, - { - "key": "label", - "itemType": "text", - "text": "Location" + "key": "source", + "itemType": "source-location", + "text": "Source" } ], "items": [ { - "label": "line: 269", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "source": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 269, + "column": 0 + } }, { - "label": "line: 270", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "source": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 270, + "column": 0 + } }, { - "label": "line: 271", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "source": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 271, + "column": 0 + } } ] } @@ -4333,20 +4404,20 @@ "type": "table", "headings": [ { - "key": "url", - "itemType": "url", - "text": "URL" - }, - { - "key": "label", - "itemType": "text", - "text": "Location" + "key": "source", + "itemType": "source-location", + "text": "Source" } ], "items": [ { - "label": "line: 341", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "source": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 341, + "column": 0 + } } ] } @@ -4482,20 +4553,20 @@ "type": "table", "headings": [ { - "key": "url", - "itemType": "url", - "text": "URL" - }, - { - "key": "label", - "itemType": "text", - "text": "Location" + "key": "source", + "itemType": "source-location", + "text": "Source" } ], "items": [ { - "label": "line: 302", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "source": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 302, + "column": 0 + } } ] } @@ -7202,31 +7273,15 @@ "lighthouse-core/audits/errors-in-console.js | description": [ "audits[errors-in-console].description" ], - "lighthouse-core/lib/i18n/i18n.js | columnURL": [ + "lighthouse-core/lib/i18n/i18n.js | columnSource": [ "audits[errors-in-console].details.headings[0].text", - "audits[server-response-time].details.headings[0].label", - "audits[image-aspect-ratio].details.headings[1].text", - "audits[image-size-responsive].details.headings[1].text", - "audits[preload-fonts].details.headings[0].text", "audits.deprecations.details.headings[1].text", - "audits[bootup-time].details.headings[0].text", - "audits[network-rtt].details.headings[0].text", - "audits[network-server-latency].details.headings[0].text", - "audits[long-tasks].details.headings[0].text", "audits[no-unload-listeners].details.headings[0].text", - "audits[unsized-images].details.headings[1].text", - "audits[uses-long-cache-ttl].details.headings[0].text", - "audits[total-byte-weight].details.headings[0].text", - "audits[render-blocking-resources].details.headings[0].label", - "audits[unminified-javascript].details.headings[0].label", - "audits[uses-webp-images].details.headings[1].label", - "audits[uses-text-compression].details.headings[0].label", - "audits[legacy-javascript].details.headings[0].label", "audits[geolocation-on-start].details.headings[0].text", "audits[no-document-write].details.headings[0].text", "audits[notification-on-start].details.headings[0].text", - "audits[uses-http2].details.headings[0].label", - "audits[uses-passive-event-listeners].details.headings[0].text" + "audits[uses-passive-event-listeners].details.headings[0].text", + "audits[font-size].details.headings[0].text" ], "lighthouse-core/lib/i18n/i18n.js | columnDescription": [ "audits[errors-in-console].details.headings[1].text" @@ -7245,6 +7300,25 @@ "path": "audits[server-response-time].displayValue" } ], + "lighthouse-core/lib/i18n/i18n.js | columnURL": [ + "audits[server-response-time].details.headings[0].label", + "audits[image-aspect-ratio].details.headings[1].text", + "audits[image-size-responsive].details.headings[1].text", + "audits[preload-fonts].details.headings[0].text", + "audits[bootup-time].details.headings[0].text", + "audits[network-rtt].details.headings[0].text", + "audits[network-server-latency].details.headings[0].text", + "audits[long-tasks].details.headings[0].text", + "audits[unsized-images].details.headings[1].text", + "audits[uses-long-cache-ttl].details.headings[0].text", + "audits[total-byte-weight].details.headings[0].text", + "audits[render-blocking-resources].details.headings[0].label", + "audits[unminified-javascript].details.headings[0].label", + "audits[uses-webp-images].details.headings[1].label", + "audits[uses-text-compression].details.headings[0].label", + "audits[legacy-javascript].details.headings[0].label", + "audits[uses-http2].details.headings[0].label" + ], "lighthouse-core/lib/i18n/i18n.js | columnTimeSpent": [ "audits[server-response-time].details.headings[1].label", "audits[mainthread-work-breakdown].details.headings[1].text", @@ -8228,12 +8302,6 @@ "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | description": [ "audits[geolocation-on-start].description" ], - "lighthouse-core/lib/i18n/i18n.js | columnLocation": [ - "audits[geolocation-on-start].details.headings[1].text", - "audits[no-document-write].details.headings[1].text", - "audits[notification-on-start].details.headings[1].text", - "audits[uses-passive-event-listeners].details.headings[1].text" - ], "lighthouse-core/audits/dobetterweb/inspector-issues.js | title": [ "audits[inspector-issues].title" ], @@ -8342,9 +8410,6 @@ "path": "audits[font-size].displayValue" } ], - "lighthouse-core/lib/i18n/i18n.js | columnSource": [ - "audits[font-size].details.headings[0].text" - ], "lighthouse-core/audits/seo/font-size.js | columnSelector": [ "audits[font-size].details.headings[1].text" ], From 3f863c03aaa6615cdd140081db9358a78320fe3b Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Wed, 13 Jan 2021 14:43:02 -0600 Subject: [PATCH 5/8] fix --- .../gather/gatherers/console-messages.js | 7 ++++++- lighthouse-core/test/results/sample_v2.json | 18 +++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/lighthouse-core/gather/gatherers/console-messages.js b/lighthouse-core/gather/gatherers/console-messages.js index fdc2dd248c5e..fba2e56e683b 100644 --- a/lighthouse-core/gather/gatherers/console-messages.js +++ b/lighthouse-core/gather/gatherers/console-messages.js @@ -42,12 +42,17 @@ class ConsoleMessages extends Gatherer { static createSourceLocation(entry) { if (!entry.url) return; + if (entry.url === "http://localhost:10200/dobetterweb/dbw_tester.js") debugger; + + const topCallFrame = entry.stackTrace && entry.stackTrace.callFrames[0]; + const column = topCallFrame ? topCallFrame.columnNumber : 0; + return { type: 'source-location', url: entry.url, urlProvider: 'network', line: entry.lineNumber || 0, - column: entry.columnNumber || 0, + column, }; } diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index 7ed7dbc3d9d1..c9d4dc53bcc3 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -819,7 +819,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.js", "urlProvider": "network", "line": 13, - "column": 0 + "column": 9 } }, { @@ -829,7 +829,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "urlProvider": "network", "line": 371, - "column": 0 + "column": 6 } }, { @@ -4295,7 +4295,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "urlProvider": "network", "line": 331, - "column": 0 + "column": 24 } }, { @@ -4304,7 +4304,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "urlProvider": "network", "line": 335, - "column": 0 + "column": 40 } } ] @@ -4344,7 +4344,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "urlProvider": "network", "line": 269, - "column": 0 + "column": 11 } }, { @@ -4353,7 +4353,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "urlProvider": "network", "line": 270, - "column": 0 + "column": 11 } }, { @@ -4362,7 +4362,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "urlProvider": "network", "line": 271, - "column": 0 + "column": 11 } } ] @@ -4478,7 +4478,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "urlProvider": "network", "line": 341, - "column": 0 + "column": 15 } } ] @@ -4647,7 +4647,7 @@ "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "urlProvider": "network", "line": 302, - "column": 0 + "column": 5 } } ] From 63bf4b2ff6c1839fc9e50e3748b6a02a59e39ebc Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Wed, 13 Jan 2021 14:58:03 -0600 Subject: [PATCH 6/8] update --- .../gather/gatherers/console-messages.js | 7 +- .../test/results/artifacts/artifacts.json | 99 ++++++++++--------- lighthouse-core/test/results/sample_v2.json | 14 +-- 3 files changed, 53 insertions(+), 67 deletions(-) diff --git a/lighthouse-core/gather/gatherers/console-messages.js b/lighthouse-core/gather/gatherers/console-messages.js index fba2e56e683b..fdc2dd248c5e 100644 --- a/lighthouse-core/gather/gatherers/console-messages.js +++ b/lighthouse-core/gather/gatherers/console-messages.js @@ -42,17 +42,12 @@ class ConsoleMessages extends Gatherer { static createSourceLocation(entry) { if (!entry.url) return; - if (entry.url === "http://localhost:10200/dobetterweb/dbw_tester.js") debugger; - - const topCallFrame = entry.stackTrace && entry.stackTrace.callFrames[0]; - const column = topCallFrame ? topCallFrame.columnNumber : 0; - return { type: 'source-location', url: entry.url, urlProvider: 'network', line: entry.lineNumber || 0, - column, + column: entry.columnNumber || 0, }; } diff --git a/lighthouse-core/test/results/artifacts/artifacts.json b/lighthouse-core/test/results/artifacts/artifacts.json index ee41bc0103ef..512ec58859d5 100644 --- a/lighthouse-core/test/results/artifacts/artifacts.json +++ b/lighthouse-core/test/results/artifacts/artifacts.json @@ -729,7 +729,7 @@ "source": "deprecation", "level": "warning", "text": "Application Cache API manifest selection is deprecated and will be removed in M85, around August 2020. See https://www.chromestatus.com/features/6192449487634432 for more details.", - "timestamp": 1607553416382.3718, + "timestamp": 1610571259470.294, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "lineNumber": 8 }, @@ -738,7 +738,7 @@ "source": "rendering", "level": "warning", "text": "HTML Imports is deprecated and has now been removed as of M80. See https://www.chromestatus.com/features/5144752345317376 and https://developers.google.com/web/updates/2019/07/web-components-time-to-upgrade for more details.", - "timestamp": 1607553416397.66, + "timestamp": 1610571259487.268, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "lineNumber": 37 }, @@ -747,7 +747,7 @@ "source": "rendering", "level": "warning", "text": "HTML Imports is deprecated and has now been removed as of M80. See https://www.chromestatus.com/features/5144752345317376 and https://developers.google.com/web/updates/2019/07/web-components-time-to-upgrade for more details.", - "timestamp": 1607553416398.7441, + "timestamp": 1610571259488.205, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "lineNumber": 38 }, @@ -756,7 +756,7 @@ "source": "other", "level": "info", "text": "Creating Application Cache with manifest http://localhost:10200/dobetterweb/clock.appcache", - "timestamp": 1607553416401.031, + "timestamp": 1610571259490.48, "url": "http://localhost:10200/dobetterweb/dbw_tester.html" }, { @@ -764,24 +764,24 @@ "source": "other", "level": "info", "text": "Application Cache Checking event", - "timestamp": 1607553416403.637, + "timestamp": 1610571259493.267, "url": "http://localhost:10200/dobetterweb/dbw_tester.html" }, { "eventType": "protocolLog", - "source": "network", + "source": "other", "level": "error", - "text": "Failed to load resource: the server responded with a status of 404 (Not Found)", - "timestamp": 1607553416961.176, - "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200" + "text": "Application Cache Error event: Manifest fetch failed (404) http://localhost:10200/dobetterweb/clock.appcache", + "timestamp": 1610571259493.3628, + "url": "http://localhost:10200/dobetterweb/dbw_tester.html" }, { "eventType": "protocolLog", - "source": "other", + "source": "network", "level": "error", - "text": "Application Cache Error event: Manifest fetch failed (404) http://localhost:10200/dobetterweb/clock.appcache", - "timestamp": 1607553418293.846, - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "text": "Failed to load resource: the server responded with a status of 404 (Not Found)", + "timestamp": 1610571260048.604, + "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200" }, { "eventType": "protocolLog", @@ -806,9 +806,10 @@ } ] }, - "timestamp": 1607553418610.9011, + "timestamp": 1610571261691.184, "url": "http://localhost:10200/dobetterweb/dbw_tester.js", - "lineNumber": 13 + "lineNumber": 13, + "columnNumber": 9 }, { "eventType": "exception", @@ -826,7 +827,7 @@ } ] }, - "timestamp": 1607553418613.646, + "timestamp": 1610571261697.4448, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "lineNumber": 57, "columnNumber": 53 @@ -847,7 +848,7 @@ } ] }, - "timestamp": 1607553418615.6199, + "timestamp": 1610571261700.9102, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "lineNumber": 60, "columnNumber": 37 @@ -857,7 +858,7 @@ "source": "network", "level": "error", "text": "Failed to load resource: the server responded with a status of 404 (Not Found)", - "timestamp": 1607553423097.062, + "timestamp": 1610571266183.4868, "url": "http://localhost:10200/dobetterweb/fcp-delayer.js?delay=5000" }, { @@ -883,9 +884,10 @@ } ] }, - "timestamp": 1607553423315.5798, + "timestamp": 1610571266303.927, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", - "lineNumber": 269 + "lineNumber": 269, + "columnNumber": 11 }, { "eventType": "protocolLog", @@ -910,9 +912,10 @@ } ] }, - "timestamp": 1607553423317.417, + "timestamp": 1610571266304.047, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", - "lineNumber": 270 + "lineNumber": 270, + "columnNumber": 11 }, { "eventType": "protocolLog", @@ -937,9 +940,10 @@ } ] }, - "timestamp": 1607553423317.817, + "timestamp": 1610571266304.96, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", - "lineNumber": 271 + "lineNumber": 271, + "columnNumber": 11 }, { "eventType": "consoleAPI", @@ -964,7 +968,7 @@ } ] }, - "timestamp": 1607553423321.635, + "timestamp": 1610571266306.376, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "lineNumber": 260, "columnNumber": 12 @@ -992,9 +996,10 @@ } ] }, - "timestamp": 1607553423339.645, + "timestamp": 1610571266308.7039, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", - "lineNumber": 302 + "lineNumber": 302, + "columnNumber": 5 }, { "eventType": "protocolLog", @@ -1019,9 +1024,10 @@ } ] }, - "timestamp": 1607553423346.242, + "timestamp": 1610571266310.699, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", - "lineNumber": 331 + "lineNumber": 331, + "columnNumber": 24 }, { "eventType": "protocolLog", @@ -1046,9 +1052,10 @@ } ] }, - "timestamp": 1607553423349.061, + "timestamp": 1610571266311.541, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", - "lineNumber": 335 + "lineNumber": 335, + "columnNumber": 40 }, { "eventType": "protocolLog", @@ -1073,9 +1080,10 @@ } ] }, - "timestamp": 1607553423352.7751, + "timestamp": 1610571266312.659, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", - "lineNumber": 341 + "lineNumber": 341, + "columnNumber": 15 }, { "eventType": "protocolLog", @@ -1100,17 +1108,10 @@ } ] }, - "timestamp": 1607553423368.14, + "timestamp": 1610571266318.583, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", - "lineNumber": 371 - }, - { - "eventType": "protocolLog", - "source": "deprecation", - "level": "warning", - "text": "/deep/ combinator is no longer supported in CSS dynamic profile. It is now effectively no-op, acting as if it were a descendant combinator. /deep/ combinator will be removed, and will be invalid at M65. You should remove it. See https://www.chromestatus.com/features/4964279606312960 for more details.", - "timestamp": 1607553424345.382, - "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + "lineNumber": 371, + "columnNumber": 6 }, { "eventType": "consoleAPI", @@ -1128,7 +1129,7 @@ } ] }, - "timestamp": 1607553424476.799, + "timestamp": 1610571267507.3171, "url": "http://localhost:10200/dobetterweb/dbw_tester.html", "lineNumber": 474, "columnNumber": 10 @@ -1138,7 +1139,7 @@ "source": "recommendation", "level": "verbose", "text": "[DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o", - "timestamp": 1607553424484.2788, + "timestamp": 1610571267517.221, "url": "http://localhost:10200/dobetterweb/dbw_tester.html" }, { @@ -1146,7 +1147,7 @@ "source": "recommendation", "level": "verbose", "text": "[DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o", - "timestamp": 1607553424484.4028, + "timestamp": 1610571267517.9739, "url": "http://localhost:10200/dobetterweb/dbw_tester.html" }, { @@ -1154,7 +1155,7 @@ "source": "recommendation", "level": "verbose", "text": "[DOM] Password field is not contained in a form: (More info: https://goo.gl/9p2vKq) %o", - "timestamp": 1607553424484.47, + "timestamp": 1610571267518.324, "url": "http://localhost:10200/dobetterweb/dbw_tester.html" }, { @@ -1162,7 +1163,7 @@ "source": "network", "level": "error", "text": "Failed to load resource: the server responded with a status of 404 (Not Found)", - "timestamp": 1607553429740.8171, + "timestamp": 1610571272820.478, "url": "http://localhost:10200/favicon.ico" }, { @@ -1170,7 +1171,7 @@ "source": "network", "level": "error", "text": "Failed to load resource: the server responded with a status of 404 (Not Found)", - "timestamp": 1607553435609.589, + "timestamp": 1610571282421.4858, "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200" } ], diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index c9d4dc53bcc3..3fecb987a3df 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -786,7 +786,7 @@ "description": "Deprecated APIs will eventually be removed from the browser. [Learn more](https://web.dev/deprecations/).", "score": 0, "scoreDisplayMode": "binary", - "displayValue": "4 warnings found", + "displayValue": "3 warnings found", "details": { "type": "table", "headings": [ @@ -831,16 +831,6 @@ "line": 371, "column": 6 } - }, - { - "value": "/deep/ combinator is no longer supported in CSS dynamic profile. It is now effectively no-op, acting as if it were a descendant combinator. /deep/ combinator will be removed, and will be invalid at M65. You should remove it. See https://www.chromestatus.com/features/4964279606312960 for more details.", - "source": { - "type": "source-location", - "url": "http://localhost:10200/dobetterweb/dbw_tester.html", - "urlProvider": "network", - "line": 0, - "column": 0 - } } ] } @@ -7552,7 +7542,7 @@ "lighthouse-core/audits/deprecations.js | displayValue": [ { "values": { - "itemCount": 4 + "itemCount": 3 }, "path": "audits.deprecations.displayValue" } From 98cb30cece35e24b24d8f5d26c228145b7d524ca Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Wed, 13 Jan 2021 16:09:36 -0600 Subject: [PATCH 7/8] move --- lighthouse-core/audits/audit.js | 16 ++++++++++++++++ lighthouse-core/audits/deprecations.js | 3 +-- lighthouse-core/audits/errors-in-console.js | 3 +-- lighthouse-core/audits/violation-audit.js | 3 +-- .../gather/gatherers/console-messages.js | 16 ---------------- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/lighthouse-core/audits/audit.js b/lighthouse-core/audits/audit.js index ad25fb83394b..ec68bee6c307 100644 --- a/lighthouse-core/audits/audit.js +++ b/lighthouse-core/audits/audit.js @@ -232,6 +232,22 @@ class Audit { }; } + /** + * @param {LH.Artifacts.ConsoleMessage} entry + * @return {LH.Audit.Details.SourceLocationValue | undefined} + */ + static makeSourceLocationFromConsoleMessage(entry) { + if (!entry.url) return; + + return { + type: 'source-location', + url: entry.url, + urlProvider: 'network', + line: entry.lineNumber || 0, + column: entry.columnNumber || 0, + }; + } + /** * @param {number|null} score * @param {LH.Audit.ScoreDisplayMode} scoreDisplayMode diff --git a/lighthouse-core/audits/deprecations.js b/lighthouse-core/audits/deprecations.js index 8c270829f929..01299661983d 100644 --- a/lighthouse-core/audits/deprecations.js +++ b/lighthouse-core/audits/deprecations.js @@ -13,7 +13,6 @@ const Audit = require('./audit.js'); const i18n = require('../lib/i18n/i18n.js'); -const ConsoleMessages = require('../gather/gatherers/console-messages.js'); const UIStrings = { /** Title of a Lighthouse audit that provides detail on the use of deprecated APIs. This descriptive title is shown to users when the page does not use deprecated APIs. */ @@ -60,7 +59,7 @@ class Deprecations extends Audit { const deprecations = entries.filter(log => log.source === 'deprecation').map(log => { return { value: log.text, - source: ConsoleMessages.createSourceLocation(log), + source: Audit.makeSourceLocationFromConsoleMessage(log), }; }); diff --git a/lighthouse-core/audits/errors-in-console.js b/lighthouse-core/audits/errors-in-console.js index b9a3b9ebac2d..c9df69054a89 100644 --- a/lighthouse-core/audits/errors-in-console.js +++ b/lighthouse-core/audits/errors-in-console.js @@ -13,7 +13,6 @@ const log = require('lighthouse-logger'); const Audit = require('./audit.js'); const i18n = require('../lib/i18n/i18n.js'); -const ConsoleMessages = require('../gather/gatherers/console-messages.js'); const UIStrings = { /** Title of a Lighthouse audit that provides detail on browser errors. This descriptive title is shown to users when no browser errors were logged into the devtools console. */ @@ -90,7 +89,7 @@ class ErrorLogs extends Audit { source: item.source, description: item.text, url: item.url, - sourceLocation: ConsoleMessages.createSourceLocation(item), + sourceLocation: Audit.makeSourceLocationFromConsoleMessage(item), }; }); diff --git a/lighthouse-core/audits/violation-audit.js b/lighthouse-core/audits/violation-audit.js index 5f058cab7542..4fd688d3d8e9 100644 --- a/lighthouse-core/audits/violation-audit.js +++ b/lighthouse-core/audits/violation-audit.js @@ -6,7 +6,6 @@ 'use strict'; const Audit = require('./audit.js'); -const ConsoleMessages = require('../gather/gatherers/console-messages.js'); class ViolationAudit extends Audit { /** @@ -27,7 +26,7 @@ class ViolationAudit extends Audit { const seen = new Set(); return artifacts.ConsoleMessages .filter(entry => entry.url && entry.source === 'violation' && pattern.test(entry.text)) - .map(entry => ConsoleMessages.createSourceLocation(entry)) + .map(Audit.makeSourceLocationFromConsoleMessage) .filter(filterUndefined) .filter(source => { // Filter out duplicate entries since they are not differentiable to the user diff --git a/lighthouse-core/gather/gatherers/console-messages.js b/lighthouse-core/gather/gatherers/console-messages.js index fdc2dd248c5e..e32ffaa477fc 100644 --- a/lighthouse-core/gather/gatherers/console-messages.js +++ b/lighthouse-core/gather/gatherers/console-messages.js @@ -35,22 +35,6 @@ function remoteObjectToString(obj) { * @implements {LH.Gatherer.FRGathererInstance} */ class ConsoleMessages extends Gatherer { - /** - * @param {LH.Artifacts.ConsoleMessage} entry - * @return {LH.Audit.Details.SourceLocationValue | undefined} - */ - static createSourceLocation(entry) { - if (!entry.url) return; - - return { - type: 'source-location', - url: entry.url, - urlProvider: 'network', - line: entry.lineNumber || 0, - column: entry.columnNumber || 0, - }; - } - /** @type {LH.Gatherer.GathererMeta} */ meta = { supportedModes: ['timespan', 'navigation'], From c46679955c3a6f48722fc4e9112a00d53bab736b Mon Sep 17 00:00:00 2001 From: Connor Clark Date: Thu, 14 Jan 2021 14:45:03 -0600 Subject: [PATCH 8/8] todo comment --- lighthouse-core/audits/errors-in-console.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lighthouse-core/audits/errors-in-console.js b/lighthouse-core/audits/errors-in-console.js index c9df69054a89..942d9142949c 100644 --- a/lighthouse-core/audits/errors-in-console.js +++ b/lighthouse-core/audits/errors-in-console.js @@ -88,6 +88,7 @@ class ErrorLogs extends Audit { return { source: item.source, description: item.text, + // TODO: remove for v8 (url is covered in sourceLocation) url: item.url, sourceLocation: Audit.makeSourceLocationFromConsoleMessage(item), };