UNPKG

lighthouse

Version:

Automated auditing, performance metrics, and best practices for the web.

104 lines (86 loc) 2.92 kB
/** * @license * Copyright 2020 Google LLC * SPDX-License-Identifier: Apache-2.0 */ /** * @fileoverview Capture IssueAdded events */ import BaseGatherer from '../base-gatherer.js'; import {NetworkRecords} from '../../computed/network-records.js'; import DevtoolsLog from './devtools-log.js'; class InspectorIssues extends BaseGatherer { /** @type {LH.Gatherer.GathererMeta<'DevtoolsLog'>} */ meta = { supportedModes: ['timespan', 'navigation'], dependencies: {DevtoolsLog: DevtoolsLog.symbol}, }; constructor() { super(); /** @type {Array<LH.Crdp.Audits.InspectorIssue>} */ this._issues = []; this._onIssueAdded = this.onIssueAdded.bind(this); } /** * @param {LH.Crdp.Audits.IssueAddedEvent} entry */ onIssueAdded(entry) { this._issues.push(entry.issue); } /** * @param {LH.Gatherer.Context} context */ async startInstrumentation(context) { const session = context.driver.defaultSession; session.on('Audits.issueAdded', this._onIssueAdded); await session.sendCommand('Audits.enable'); } /** * @param {LH.Gatherer.Context} context */ async stopInstrumentation(context) { const session = context.driver.defaultSession; session.off('Audits.issueAdded', this._onIssueAdded); await session.sendCommand('Audits.disable'); } /** * @param {LH.Gatherer.Context<'DevtoolsLog'>} context * @return {Promise<LH.Artifacts.InspectorIssues>} */ async getArtifact(context) { const devtoolsLog = context.dependencies.DevtoolsLog; const networkRecords = await NetworkRecords.request(devtoolsLog, context); /** @type {LH.Artifacts.InspectorIssues} */ const artifact = {}; for (const issue of this._issues) { const detailsKey = /** @type {keyof LH.Crdp.Audits.InspectorIssueDetails} */( Object.keys(issue.details)[0]); const details = issue.details[detailsKey]; if (!details) { continue; } const artifactKey = /** @type {LH.Artifacts.InspectorIssuesKeyToArtifactKey<typeof detailsKey>} */( detailsKey.replace('Details', '')); // Duplicate issues can occur for the same request; only use the one with a matching networkRequest. const requestId = 'request' in details && details.request && details.request.requestId; if (requestId) { if (networkRecords.find(req => req.requestId === requestId)) { if (!artifact[artifactKey]) { artifact[artifactKey] = []; } // @ts-expect-error - detail types are not all compatible artifact[artifactKey].push(details); } } else { if (!artifact[artifactKey]) { artifact[artifactKey] = []; } // @ts-expect-error - detail types are not all compatible artifact[artifactKey].push(details); } } return artifact; } } export default InspectorIssues;