lighthouse
Version:
Automated auditing, performance metrics, and best practices for the web.
914 lines (842 loc) • 34 kB
TypeScript
/**
* @license
* Copyright 2018 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {Protocol as Crdp} from 'devtools-protocol/types/protocol.js';
import * as TraceEngine from '@paulirish/trace_engine';
import * as Lantern from '../core/lib/lantern/lantern.js';
import {parseManifest} from '../core/lib/manifest-parser.js';
import {LighthouseError} from '../core/lib/lh-error.js';
import {NetworkRequest as _NetworkRequest} from '../core/lib/network-request.js';
import speedline from 'speedline-core';
import * as CDTSourceMap from '../core/lib/cdt/generated/SourceMap.js';
import {ArbitraryEqualityMap} from '../core/lib/arbitrary-equality-map.js';
import type { TaskNode as _TaskNode } from '../core/lib/tracehouse/main-thread-tasks.js';
import AuditDetails from './lhr/audit-details.js'
import Config from './config.js';
import Gatherer from './gatherer.js';
import {IEntity} from 'third-party-web';
import {IcuMessage} from './lhr/i18n.js';
import LHResult from './lhr/lhr.js'
import Protocol from './protocol.js';
import Util from './utility-types.js';
import Audit from './audit.js';
export type Artifacts = BaseArtifacts & GathererArtifacts;
/**
* Artifacts always created by gathering. These artifacts are available to Lighthouse plugins.
* NOTE: any breaking changes here are considered breaking Lighthouse changes that must be done
* on a major version bump.
*/
export type BaseArtifacts = UniversalBaseArtifacts & ContextualBaseArtifacts;
/**
* The set of base artifacts that are available in every mode of Lighthouse operation.
*/
interface UniversalBaseArtifacts {
/** The ISO-8601 timestamp of when the test page was fetched and artifacts collected. */
fetchTime: string;
/** A set of warnings about unexpected things encountered while loading and testing the page. */
LighthouseRunWarnings: Array<string | IcuMessage>;
/** The benchmark index that indicates rough device class. */
BenchmarkIndex: number;
/** An object containing information about the testing configuration used by Lighthouse. */
settings: Config.Settings;
/** The timing instrumentation of the gather portion of a run. */
Timing: Artifacts.MeasureEntry[];
/** The host's device pixel ratio. */
HostDPR: number;
/** Device which Chrome is running on. */
HostFormFactor: 'desktop'|'mobile';
/** The user agent string of the version of Chrome used. */
HostUserAgent: string;
/** The product string of the version of Chrome used. Example: HeadlessChrome/123.2.2.0 would be from old headless. */
HostProduct: string;
/** Information about how Lighthouse artifacts were gathered. */
GatherContext: {gatherMode: Gatherer.GatherMode};
}
/**
* The set of base artifacts whose semantics differ or may be valueless in certain Lighthouse gather modes.
*/
interface ContextualBaseArtifacts {
/** The URL initially requested and the post-redirects URL that was actually loaded. */
URL: Artifacts.URL;
/** If loading the page failed, value is the error that caused it. Otherwise null. */
PageLoadError: LighthouseError | null;
}
/**
* Artifacts provided by the default gatherers that are exposed to plugins with a hardended API.
* NOTE: any breaking changes here are considered breaking Lighthouse changes that must be done
* on a major version bump.
*/
interface PublicGathererArtifacts {
/** ConsoleMessages deprecation and intervention warnings, console API calls, and exceptions logged by Chrome during page load. */
ConsoleMessages: Artifacts.ConsoleMessage[];
/** The primary log of devtools protocol activity. */
DevtoolsLog: DevtoolsLog;
/** Information on size and loading for all the images in the page. Natural size information for `picture` and CSS images is only available if the image was one of the largest 50 images. */
ImageElements: Artifacts.ImageElement[];
/** All the link elements on the page or equivalently declared in `Link` headers. @see https://html.spec.whatwg.org/multipage/links.html */
LinkElements: Artifacts.LinkElement[];
/** The contents of the main HTML document network resource. */
MainDocumentContent: string;
/** The values of the <meta> elements in the head. */
MetaElements: Array<{name?: string, content?: string, property?: string, httpEquiv?: string, charset?: string, node: Artifacts.NodeDetails}>;
/** Information on all scripts in the page. */
Scripts: Artifacts.Script[];
/** The primary trace taken over the entire run. */
Trace: Trace;
/** The dimensions and devicePixelRatio of the loaded viewport. */
ViewportDimensions: Artifacts.ViewportDimensions;
}
/**
* Artifacts provided by the default gatherers. Augment this interface when adding additional
* gatherers. Changes to these artifacts are not considered a breaking Lighthouse change.
*/
export interface GathererArtifacts extends PublicGathererArtifacts {
/** The results of running the aXe accessibility tests on the page. */
Accessibility: Artifacts.Accessibility;
/** Array of all anchors on the page. */
AnchorElements: Artifacts.AnchorElement[];
/** Errors when attempting to use the back/forward cache. */
BFCacheFailures: Artifacts.BFCacheFailure[];
/** CSS coverage information for styles used by page's final state. */
CSSUsage: Crdp.CSS.RuleUsage[];
/** The log of devtools protocol activity if there was a page load error and Chrome navigated to a `chrome-error://` page. */
DevtoolsLogError: DevtoolsLog;
/** Information on the document's doctype(or null if not present), specifically the name, publicId, and systemId.
All properties default to an empty string if not present */
Doctype: Artifacts.Doctype | null;
/** All the iframe elements in the page. */
IFrameElements: Artifacts.IFrameElement[];
/** All the input elements, including associated form and label elements. */
Inputs: {inputs: Artifacts.InputElement[]; forms: Artifacts.FormElement[]; labels: Artifacts.LabelElement[]};
/** Screenshot of the entire page (rather than just the above the fold content). */
FullPageScreenshot: LHResult.FullPageScreenshot | null;
/** The issues surfaced in the devtools Issues panel */
InspectorIssues: Artifacts.InspectorIssues;
/** JS coverage information for code used during audit. Keyed by script id. */
// 'url' is excluded because it can be overridden by a magic sourceURL= comment, which makes keeping it a dangerous footgun!
JsUsage: Record<string, Omit<Crdp.Profiler.ScriptCoverage, 'url'>>;
/** The user agent string that Lighthouse used to load the page. Set to the empty string if unknown. */
NetworkUserAgent: string;
/** Information on fetching and the content of the /robots.txt file. */
RobotsTxt: {status: number|null, content: string|null, errorMessage?: string};
/** Source maps of scripts executed in the page. */
SourceMaps: Array<Artifacts.SourceMap>;
/** Information on detected tech stacks (e.g. JS libraries) used by the page. */
Stacks: Artifacts.DetectedStack[];
/** CSS stylesheets found on the page. */
Stylesheets: Artifacts.CSSStyleSheetInfo[];
/** The trace if there was a page load error and Chrome navigated to a `chrome-error://` page. */
TraceError: Trace;
/** Elements associated with metrics (ie: Largest Contentful Paint element). */
TraceElements: Artifacts.TraceElement[];
}
declare module Artifacts {
type ComputedContext = Util.Immutable<{
computedCache: Map<string, ArbitraryEqualityMap>;
}>;
type NetworkRequest = _NetworkRequest;
type TaskNode = _TaskNode;
type TBTImpactTask = TaskNode & {tbtImpact: number, selfTbtImpact: number, selfBlockingTime: number};
type MetaElement = Artifacts['MetaElements'][0];
interface URL {
/**
* URL of the initially requested URL during a Lighthouse navigation.
* Will be `undefined` in timespan/snapshot.
*/
requestedUrl?: string;
/**
* URL of the last document request during a Lighthouse navigation.
* Will be `undefined` in timespan/snapshot.
*/
mainDocumentUrl?: string;
/** URL displayed on the page after Lighthouse finishes. */
finalDisplayedUrl: string;
}
type Rect = AuditDetails.Rect;
interface NodeDetails {
lhId: string,
devtoolsNodePath: string,
selector: string,
boundingRect: Rect,
snippet: string,
nodeLabel: string,
explanation?: string,
}
interface RuleExecutionError {
name: string;
message: string;
}
interface AxeRuleResult {
id: string;
impact?: string;
tags: Array<string>;
nodes: Array<{
target: Array<string|string[]>;
failureSummary?: string;
node: NodeDetails;
relatedNodes: NodeDetails[];
}>;
error?: RuleExecutionError;
}
interface Accessibility {
violations: Array<AxeRuleResult>;
notApplicable: Array<Pick<AxeRuleResult, 'id'>>;
passes: Array<Pick<AxeRuleResult, 'id'>>;
incomplete: Array<AxeRuleResult>;
version: string;
}
interface CSSStyleSheetInfo {
header: Crdp.CSS.CSSStyleSheetHeader;
content: string;
}
interface Doctype {
name: string;
publicId: string;
systemId: string;
documentCompatMode: string;
}
interface IFrameElement {
/** The `id` attribute of the iframe. */
id: string,
/** Details for node in DOM for the iframe element */
node: NodeDetails,
/** The `src` attribute of the iframe. */
src: string,
/** The iframe's ClientRect. @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect */
clientRect: {
top: number;
bottom: number;
left: number;
right: number;
width: number;
height: number;
},
/** If the iframe or an ancestor of the iframe is fixed in position. */
isPositionFixed: boolean,
}
/** @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#Attributes */
interface LinkElement {
/** The `rel` attribute of the link, normalized to lower case. @see https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types */
rel: 'alternate'|'canonical'|'dns-prefetch'|'preconnect'|'preload'|'stylesheet'|string;
/** The `href` attribute of the link or `null` if it was invalid in the header. */
href: string | null
/** The raw value of the `href` attribute. Only different from `href` when source is 'headers' */
hrefRaw: string
/** The `hreflang` attribute of the link */
hreflang: string
/** The `as` attribute of the link */
as: string
/** The `crossOrigin` attribute of the link */
crossOrigin: string | null
/** Where the link was found, either in the DOM or in the headers of the main document */
source: 'head'|'body'|'headers'
node: NodeDetails | null
/** The fetch priority hint for preload links. */
fetchPriority?: string;
}
interface Script extends Omit<Crdp.Debugger.ScriptParsedEvent, 'url'|'embedderName'> {
/**
* Set by a sourceURL= magic comment if present, otherwise this is the same as the URL.
* Use this field for presentational purposes only.
*/
name: string;
url: string;
content?: string;
}
/** @see https://sourcemaps.info/spec.html#h.qz3o9nc69um5 */
type RawSourceMap = {
/** File version and must be a positive integer. */
version: number
/** A list of original source files used by the `mappings` entry. */
sources: string[]
/** A list of symbol names used by the `mappings` entry. */
names?: string[]
/** An optional source root, useful for relocating source files on a server or removing repeated values in the `sources` entry. This value is prepended to the individual entries in the `source` field. */
sourceRoot?: string
/** An optional list of source content, useful when the `source` can’t be hosted. The contents are listed in the same order as the sources. */
sourcesContent?: string[]
/** A string with the encoded mapping data. */
mappings: string
/** An optional name of the generated code (the bundled code that was the result of this build process) that this source map is associated with. */
file?: string
/**
* An optional array of maps that are associated with an offset into the generated code.
* `map` is optional because the spec defines that either `url` or `map` must be defined.
* We explicitly only support `map` here.
*/
sections?: Array<{offset: {line: number, column: number}, map?: RawSourceMap}>
}
/**
* Source map for a given script found at scriptUrl. If there is an error in fetching or
* parsing the map, errorMessage will be defined instead of map.
*/
type SourceMap = {
/** The DevTools protocol script identifier. */
scriptId: string;
/** URL of code that source map applies to. */
scriptUrl: string
/** URL of the source map. undefined if from data URL. */
sourceMapUrl?: string
/** Source map data structure. */
map: RawSourceMap
} | {
/** The DevTools protocol script identifier. */
scriptId: string;
/** URL of code that source map applies to. */
scriptUrl: string
/** URL of the source map. undefined if from data URL. */
sourceMapUrl?: string
/** Error that occurred during fetching or parsing of source map. */
errorMessage: string
/** No map on account of error. */
map?: undefined;
}
interface Bundle {
rawMap: RawSourceMap;
script: Artifacts.Script;
map: CDTSourceMap;
sizes: {
// TODO(cjamcl): Rename to `sources`.
files: Record<string, number>;
unmappedBytes: number;
totalBytes: number;
} | {errorMessage: string};
}
/** @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#Attributes */
interface AnchorElement {
rel: string
/** The computed href property: https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-88517319, use `rawHref` for the exact attribute value */
href: string
/** The exact value of the href attribute value, as it is in the DOM */
rawHref: string
name?: string
text: string
textLang?: string
role: string
target: string
node: NodeDetails
onclick: string
id: string
attributeNames: Array<string>
listeners?: Array<{
type: Crdp.DOMDebugger.EventListener['type']
}>
}
type BFCacheReasonMap = {
[key in Crdp.Page.BackForwardCacheNotRestoredReason]?: string[];
};
type BFCacheNotRestoredReasonsTree = Record<Crdp.Page.BackForwardCacheNotRestoredReasonType, BFCacheReasonMap>;
interface BFCacheFailure {
notRestoredReasonsTree: BFCacheNotRestoredReasonsTree;
}
// TODO(bckenny): real type for parsed manifest.
type Manifest = ReturnType<typeof parseManifest>;
interface ImageElement {
/** The resolved source URL of the image. Similar to `currentSrc`, but resolved for CSS images as well. */
src: string;
/** The srcset attribute value. @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset */
srcset: string;
/** The displayed width of the image, uses img.width when available falling back to clientWidth. See https://codepen.io/patrickhulce/pen/PXvQbM for examples. */
displayedWidth: number;
/** The displayed height of the image, uses img.height when available falling back to clientHeight. See https://codepen.io/patrickhulce/pen/PXvQbM for examples. */
displayedHeight: number;
/** The raw width attribute of the image element. CSS images will be set to null. */
attributeWidth: string | null;
/** The raw height attribute of the image element. CSS images will be set to null. */
attributeHeight: string | null;
/**
* The natural width and height of the underlying image resource, uses img.naturalHeight/img.naturalWidth. See https://codepen.io/patrickhulce/pen/PXvQbM for examples.
* Set to `undefined` if the data could not be collected.
*/
naturalDimensions?: {
width: number;
height: number;
};
/**
* The width/height of the element as defined by matching CSS rules.
* These are distinct from the `computedStyles` properties in that they are the raw property value.
* e.g. `width` would be `"100vw"`, not the computed width in pixels.
* Set to `undefined` if the data was not collected.
*/
cssEffectiveRules?: {
/** The width of the image as expressed by CSS rules. Set to `null` if there was no width set in CSS. */
width: string | null;
/** The height of the image as expressed by CSS rules. Set to `null` if there was no height set in CSS. */
height: string | null;
/** The aspect ratio of the image as expressed by CSS rules. Set to `null` if there was no aspect ratio set in CSS. */
aspectRatio: string | null;
};
/** The computed styles as determined by `getComputedStyle`. */
computedStyles: {
/** CSS `position` property. */
position: string;
/** CSS `object-fit` property. */
objectFit: string;
/** CSS `image-rendering` propertry. */
imageRendering: string;
};
/** The BoundingClientRect of the element. */
clientRect: {
top: number;
bottom: number;
left: number;
right: number;
};
/** Flags whether this element was an image via CSS background-image rather than <img> tag. */
isCss: boolean;
/** Flags whether this element was contained within a <picture> tag. */
isPicture: boolean;
/** Flags whether this element was contained within a ShadowRoot */
isInShadowDOM: boolean;
/** Details for node in DOM for the image element */
node: NodeDetails;
/** The loading attribute of the image. */
loading?: string;
/** The fetch priority hint for HTMLImageElements. */
fetchPriority?: string;
}
interface TraceElement {
traceEventType: 'trace-engine'|'layout-shift'|'animation';
node: NodeDetails;
nodeId: number;
animations?: {name?: string, failureReasonsMask?: number, unsupportedProperties?: string[]}[];
type?: string;
}
interface TraceEngineResult {
data: TraceEngine.Handlers.Types.HandlerData;
insights: TraceEngine.Insights.Types.TraceInsightSets;
}
interface TraceEngineRootCauses {
layoutShifts: Map<TraceEngine.Types.Events.SyntheticLayoutShift, TraceEngine.Insights.Models.CLSCulprits.LayoutShiftRootCausesData>;
}
interface ViewportDimensions {
innerWidth: number;
innerHeight: number;
outerWidth: number;
outerHeight: number;
devicePixelRatio: number;
}
type Replace<T extends string, S extends string, D extends string,
A extends string = ""> = T extends `${infer L}${S}${infer R}` ?
Replace<R, S, D, `${A}${L}${D}`> : `${A}${T}`;
export type InspectorIssuesKeyToArtifactKey<T extends string> = Replace<T, 'Details', ''>;
export type InspectorIssues = {
[x in keyof Crdp.Audits.InspectorIssueDetails as InspectorIssuesKeyToArtifactKey<x>]: Array<Exclude<Crdp.Audits.InspectorIssueDetails[x], undefined>>
};
// Computed artifact types below.
type CriticalRequestNode = {
[id: string]: {
request: Artifacts.NetworkRequest;
children: CriticalRequestNode;
}
}
type MeasureEntry = LHResult.MeasureEntry;
interface MetricComputationDataInput {
devtoolsLog: DevtoolsLog;
trace: Trace;
settings: Audit.Context['settings'];
gatherContext: Artifacts['GatherContext'];
simulator: Gatherer.Simulation.Simulator | null;
URL: Artifacts['URL'];
SourceMaps: Artifacts['SourceMaps'];
HostDPR: Artifacts['HostDPR'];
}
interface MetricComputationData extends MetricComputationDataInput {
networkRecords: Array<Artifacts.NetworkRequest>;
processedTrace: ProcessedTrace;
processedNavigation?: ProcessedNavigation;
}
interface NavigationMetricComputationData extends MetricComputationData {
processedNavigation: ProcessedNavigation;
}
interface Metric {
timing: number;
timestamp?: number;
}
interface NetworkAnalysis {
rtt: number;
additionalRttByOrigin: Map<string, number>;
serverResponseTimeByOrigin: Map<string, number>;
throughput: number;
}
type LanternMetric = Lantern.Metrics.MetricResult<Artifacts.NetworkRequest>;
type Speedline = speedline.Output<'speedIndex'>;
interface TraceTimes {
timeOrigin: number;
traceEnd: number;
}
interface NavigationTraceTimes {
timeOrigin: number;
firstPaint?: number;
firstContentfulPaint: number;
firstContentfulPaintAllFrames: number;
largestContentfulPaint?: number;
largestContentfulPaintAllFrames?: number;
traceEnd: number;
load?: number;
domContentLoaded?: number;
}
interface ProcessedTrace {
/** The raw timestamps of key events, in microseconds. */
timestamps: TraceTimes;
/** The relative times from timeOrigin to key events, in milliseconds. */
timings: TraceTimes;
/** The subset of trace events from the main frame's process, sorted by timestamp. Due to cross-origin navigations, the main frame may have multiple processes, so events may be from more than one process. */
processEvents: Array<TraceEvent>;
/** The subset of trace events from the page's main thread, sorted by timestamp. */
mainThreadEvents: Array<TraceEvent>;
/** The subset of trace events from the main frame, sorted by timestamp. */
frameEvents: Array<TraceEvent>;
/** The subset of trace events from the main frame and any child frames, sorted by timestamp. */
frameTreeEvents: Array<TraceEvent>;
/** IDs for the trace's main frame, and process. The startingPid is the initial process id, however cross-origin navigations may incur changes to the pid while the frame ID remains identical. */
mainFrameInfo: {startingPid: number, frameId: string};
/** The list of frames committed in the trace. */
frames: Array<{id: string, url: string}>;
/** The trace event marking the time at which the run should consider to have begun. Typically the same as the navigationStart but might differ due to SPA navigations, client-side redirects, etc. In the timespan case, this event is injected by Lighthouse itself. */
timeOriginEvt: TraceEvent;
/** All received trace events subsetted to important categories. */
_keyEvents: Array<TraceEvent>;
/** Map where keys are process IDs and their values are thread IDs */
_rendererPidToTid: Map<number, number>;
}
interface ProcessedNavigation {
/** The raw timestamps of key metric events, in microseconds. */
timestamps: NavigationTraceTimes;
/** The relative times from navigationStart to key metric events, in milliseconds. */
timings: NavigationTraceTimes;
/** The trace event marking firstPaint, if it was found. */
firstPaintEvt?: TraceEvent;
/** The trace event marking firstContentfulPaint, if it was found. */
firstContentfulPaintEvt: TraceEvent;
/** The trace event marking firstContentfulPaint from all frames, if it was found. */
firstContentfulPaintAllFramesEvt: TraceEvent;
/** The trace event marking largestContentfulPaint, if it was found. */
largestContentfulPaintEvt?: TraceEvent;
/** The trace event marking largestContentfulPaint from all frames, if it was found. */
largestContentfulPaintAllFramesEvt?: TraceEvent;
/** The trace event marking loadEventEnd, if it was found. */
loadEvt?: TraceEvent;
/** The trace event marking domContentLoadedEventEnd, if it was found. */
domContentLoadedEvt?: TraceEvent;
/** Whether LCP was invalidated without a new candidate. */
lcpInvalidated: boolean;
}
/** Information on a tech stack (e.g. a JS library) used by the page. */
interface DetectedStack {
/** The identifier for how this stack was detected. */
detector: 'js';
/** The unique string ID for the stack. */
id: string;
/** The name of the stack. */
name: string;
/** The version of the stack, if it could be detected. */
version?: string;
/** The package name on NPM, if it exists. */
npm?: string;
}
interface TimingSummary {
firstContentfulPaint: number | undefined;
firstContentfulPaintTs: number | undefined;
firstContentfulPaintAllFrames: number | undefined;
firstContentfulPaintAllFramesTs: number | undefined;
largestContentfulPaint: number | undefined;
largestContentfulPaintTs: number | undefined;
largestContentfulPaintAllFrames: number | undefined;
largestContentfulPaintAllFramesTs: number | undefined;
timeToFirstByte: number | undefined;
timeToFirstByteTs: number | undefined;
lcpLoadDelay: number | undefined;
lcpLoadDuration: number | undefined;
lcpRenderDelay: number | undefined;
interactive: number | undefined;
interactiveTs: number | undefined;
speedIndex: number | undefined;
speedIndexTs: number | undefined;
maxPotentialFID: number | undefined;
cumulativeLayoutShift: number | undefined;
cumulativeLayoutShiftMainFrame: number | undefined;
totalBlockingTime: number | undefined;
observedTimeOrigin: number;
observedTimeOriginTs: number;
observedNavigationStart: number | undefined;
observedNavigationStartTs: number | undefined;
observedCumulativeLayoutShift: number | undefined;
observedCumulativeLayoutShiftMainFrame: number | undefined;
observedFirstPaint: number | undefined;
observedFirstPaintTs: number | undefined;
observedFirstContentfulPaint: number | undefined;
observedFirstContentfulPaintTs: number | undefined;
observedFirstContentfulPaintAllFrames: number | undefined;
observedFirstContentfulPaintAllFramesTs: number | undefined;
observedLargestContentfulPaint: number | undefined;
observedLargestContentfulPaintTs: number | undefined;
observedLargestContentfulPaintAllFrames: number | undefined;
observedLargestContentfulPaintAllFramesTs: number | undefined;
observedTraceEnd: number | undefined;
observedTraceEndTs: number | undefined;
observedLoad: number | undefined;
observedLoadTs: number | undefined;
observedDomContentLoaded: number | undefined;
observedDomContentLoadedTs: number | undefined;
observedFirstVisualChange: number;
observedFirstVisualChangeTs: number;
observedLastVisualChange: number;
observedLastVisualChangeTs: number;
observedSpeedIndex: number;
observedSpeedIndexTs: number;
}
interface FormElement {
id: string;
name: string;
autocomplete: string;
node: NodeDetails;
}
/** Attributes collected for every input element in the inputs array from the forms interface. */
interface InputElement {
/** If set, the parent form is the index into the associated FormElement array. Otherwise, the input element has no parent form. */
parentFormIndex?: number;
/** Array of indices into associated LabelElement array. */
labelIndices: number[];
id: string;
name: string;
type: string;
placeholder?: string;
autocomplete: {
property: string;
attribute: string | null;
prediction: string | null;
};
preventsPaste?: boolean;
node: NodeDetails;
}
/** Attributes collected for every label element in the labels array from the forms interface */
interface LabelElement {
for: string;
node: NodeDetails;
}
/** Describes a generic console message. */
interface BaseConsoleMessage {
/**
* The text printed to the console, as shown on the browser console.
*
* For console API calls, all values are formatted into the text. Primitive values and
* function will be printed as-is while objects will be formatted as if the object were
* passed to String(). For example, a div will be formatted as "[object HTMLDivElement]".
*
* For exceptions the text will be the same as err.message at runtime.
*/
text: string;
/** Time of the console log in milliseconds since epoch. */
timestamp: number;
/** The stack trace of the log/exception, if known. */
stackTrace?: Crdp.Runtime.StackTrace;
/** The URL of the log/exception, if known. */
url?: string;
/** The script id of the log/exception, if known. */
scriptId?: string;
/** Line number in the script (0-indexed), if known. */
lineNumber?: number;
/** Column number in the script (0-indexed), if known. */
columnNumber?: number;
}
/** Describes a console message logged by a script using the console API. */
interface ConsoleAPICall extends BaseConsoleMessage {
eventType: 'consoleAPI';
/** The console API invoked. Only the following console API calls are gathered. */
source: 'console.warn' | 'console.error';
/** Corresponds to the API call. */
level: 'warning' | 'error';
}
interface ConsoleException extends BaseConsoleMessage {
eventType: 'exception';
source: 'exception';
level: 'error';
}
/**
* Describes a report logged to the console by the browser regarding interventions,
* deprecations, violations, and more.
*/
interface ConsoleProtocolLog extends BaseConsoleMessage {
source: Crdp.Log.LogEntry['source'],
level: Crdp.Log.LogEntry['level'],
eventType: 'protocolLog';
}
type ConsoleMessage = ConsoleAPICall | ConsoleException | ConsoleProtocolLog;
interface ImageElementRecord extends ImageElement {
/** The MIME type of the underlying image file. */
mimeType?: string;
}
interface Entity extends IEntity {
isUnrecognized?: boolean;
}
interface EntityClassification {
urlsByEntity: Map<Entity, Set<string>>;
entityByUrl: Map<string, Entity>;
firstParty?: Entity;
// Convenience methods.
isFirstParty: (url: string) => boolean;
}
interface TraceImpactedNode {
node_id: number;
old_rect?: Array<number>;
new_rect?: Array<number>;
}
}
export interface Trace {
traceEvents: TraceEvent[];
metadata?: {
'cpu-family'?: number;
};
[futureProps: string]: any;
}
/** The type of the Profile & ProfileChunk event in Chromium traces. Note that this is subtly different from Crdp.Profiler.Profile. */
export interface TraceCpuProfile {
nodes?: Array<{id: number, callFrame: {functionName: string, url?: string}, parent?: number}>
samples?: Array<number>
timeDeltas?: Array<number>
}
/**
* @see https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
*/
export interface TraceEvent {
name: string;
cat: string;
args: {
fileName?: string;
snapshot?: string;
sync_id?: string;
beginData?: {
frame?: string;
startLine?: number;
url?: string;
};
data?: {
frame?: string;
parent?: string;
frameID?: string;
frameTreeNodeId?: number;
isMainFrame?: boolean;
persistentIds?: boolean,
processId?: number;
isLoadingMainFrame?: boolean;
documentLoaderURL?: string;
navigationId?: string;
frames?: {
frame: string;
url: string;
parent?: string;
processId?: number;
name?: string;
}[];
page?: string;
readyState?: number;
requestId?: string;
startTime?: number;
timeDeltas?: TraceCpuProfile['timeDeltas'];
cpuProfile?: TraceCpuProfile;
callFrame?: Required<TraceCpuProfile>['nodes'][0]['callFrame']
/** Marker for each synthetic CPU profiler event for the range of _potential_ ts values. */
_syntheticProfilerRange?: {
earliestPossibleTimestamp: number
latestPossibleTimestamp: number
}
stackTrace?: {
url: string
}[];
styleSheetUrl?: string;
timerId?: string;
url?: string;
is_main_frame?: boolean;
cumulative_score?: number;
id?: string;
nodeId?: number;
DOMNodeId?: number;
imageUrl?: string;
impacted_nodes?: Artifacts.TraceImpactedNode[];
score?: number;
weighted_score_delta?: number;
had_recent_input?: boolean;
compositeFailed?: number;
unsupportedProperties?: string[];
size?: number;
/** Responsiveness data. */
interactionType?: 'drag'|'keyboard'|'tapOrClick';
maxDuration?: number;
type?: string;
functionName?: string;
name?: string;
duration?: number;
blockingDuration?: number;
candidateIndex?: number;
priority?: string;
requestMethod?: string;
resourceType?: string;
fromCache?: boolean;
fromServiceWorker?: boolean;
mimeType?: string;
statusCode?: number;
timing?: any;
connectionId?: number;
connectionReused?: boolean;
encodedDataLength?: number;
decodedBodyLength?: number;
initiator?: {type: string, url?: string, stack?: any};
protocol?: string;
finishTime?: number;
headers?: Array<{name: string, value: string}>;
};
frame?: string;
name?: string;
labels?: string;
};
pid: number;
tid: number;
/** Timestamp of the event in microseconds. */
ts: number;
dur: number;
ph: 'B'|'b'|'D'|'E'|'e'|'F'|'I'|'M'|'N'|'n'|'O'|'R'|'S'|'T'|'X';
s?: 't';
id?: string;
id2?: {
local?: string;
};
}
declare module Trace {
/**
* Base event of a `ph: 'X'` 'complete' event. Extend with `name` and `args` as
* needed.
*/
interface CompleteEvent {
ph: 'X';
cat: string;
pid: number;
tid: number;
dur: number;
ts: number;
tdur: number;
tts: number;
}
/**
* Base event of a `ph: 'b'|'e'|'n'` async event. Extend with `name`, `args`, and
* more specific `ph` (if needed).
*/
interface AsyncEvent {
ph: 'b'|'e'|'n';
cat: string;
pid: number;
tid: number;
ts: number;
id: string;
scope?: string;
// TODO(bckenny): No dur on these. Sort out optional `dur` on trace events.
/** @deprecated there is no `dur` on async events. */
dur: number;
}
}
/**
* A record of DevTools Debugging Protocol events.
*/
export type DevtoolsLog = Array<Protocol.RawEventMessage>;