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)
}
}
}