import FRGatherer from 'lighthouse/lighthouse-core/fraggle-rock/gather/session.js' import pageFunctions from 'lighthouse/lighthouse-core/lib/page-functions.js' import NetworkRecorder from 'lighthouse/lighthouse-core/lib/network-recorder.js' import InstallabilityErrors from 'lighthouse/lighthouse-core/gather/gatherers/installability-errors.js' import WebAppManifest from 'lighthouse/lighthouse-core/gather/gatherers/web-app-manifest.js' import LinkElements from 'lighthouse/lighthouse-core/gather/gatherers/link-elements.js' import ViewportDimensions from 'lighthouse/lighthouse-core/gather/gatherers/viewport-dimensions.js' import serviceWorkers from 'lighthouse/lighthouse-core/gather/driver/service-workers.js' import type { CDPSession } from 'puppeteer-core/lib/esm/puppeteer/api/CDPSession.js' import type { Page } from 'puppeteer-core/lib/esm/puppeteer/api/Page.js' import collectMetaElements from '../scripts/collectMetaElements.js' import { NETWORK_RECORDER_EVENTS } from '../constants.js' import type { GathererDriver } from '../types.js' export default class PWAGatherer { private _frGatherer: typeof FRGatherer private _networkRecorder: typeof NetworkRecorder private _networkRecords: typeof NetworkRecorder[] = [] constructor ( private _session: CDPSession, private _page: Page, private _driver: GathererDriver ) { this._frGatherer = new FRGatherer(this._session) /** * setup network recorder */ this._networkRecorder = new NetworkRecorder() NETWORK_RECORDER_EVENTS.forEach((method) => { this._session.on(method, (params) => this._networkRecorder.dispatch({ method, params })) }) /** * clean up network records after every page load */ this._page.on('load', () => { this._networkRecords = this._networkRecorder.getRawRecords() delete this._networkRecorder this._networkRecorder = new NetworkRecorder() }) } async gatherData () { const pageUrl = await this._page?.url() const passContext = { url: pageUrl, driver: this._driver } const loadData = { networkRecords: this._networkRecords } const linkElements = new LinkElements() const viewportDimensions = new ViewportDimensions() const { registrations } = await serviceWorkers.getServiceWorkerRegistrations(this._frGatherer) const { versions } = await serviceWorkers.getServiceWorkerVersions(this._frGatherer) return { URL: { requestedUrl: pageUrl, finalUrl: pageUrl }, WebAppManifest: await WebAppManifest.getWebAppManifest(this._frGatherer, pageUrl), InstallabilityErrors: await InstallabilityErrors.getInstallabilityErrors(this._frGatherer), MetaElements: await this._driver.evaluate(collectMetaElements, { args: [], useIsolation: true, deps: [pageFunctions.getElementsInDocument], }), ViewportDimensions: await viewportDimensions.afterPass(passContext), ServiceWorker: { versions, registrations }, LinkElements: await linkElements.afterPass(passContext, loadData) } } }