diff --git a/lighthouse-core/fraggle-rock/api.js b/lighthouse-core/fraggle-rock/api.js index 43cdc3741789..a20720ce4f88 100644 --- a/lighthouse-core/fraggle-rock/api.js +++ b/lighthouse-core/fraggle-rock/api.js @@ -5,61 +5,10 @@ */ 'use strict'; -const Driver = require('./gather/driver.js'); -const Runner = require('../runner.js'); -const {initializeConfig} = require('./config/config.js'); - -/** @param {{page: import('puppeteer').Page, config?: LH.Config.Json}} options */ -async function snapshot(options) { - const {config} = initializeConfig(options.config, {gatherMode: 'snapshot'}); - const driver = new Driver(options.page); - await driver.connect(); - - const url = await options.page.url(); - - return Runner.run( - async () => { - /** @type {LH.BaseArtifacts} */ - const baseArtifacts = { - fetchTime: new Date().toJSON(), - LighthouseRunWarnings: [], - URL: {requestedUrl: url, finalUrl: url}, - Timing: [], - Stacks: [], - settings: config.settings, - // TODO(FR-COMPAT): convert these to regular artifacts - HostFormFactor: 'mobile', - HostUserAgent: 'unknown', - NetworkUserAgent: 'unknown', - BenchmarkIndex: 0, - InstallabilityErrors: {errors: []}, - traces: {}, - devtoolsLogs: {}, - WebAppManifest: null, - PageLoadError: null, - }; - - /** @type {Partial} */ - const artifacts = {}; - - for (const {id, gatherer} of config.artifacts || []) { - const artifactName = /** @type {keyof LH.GathererArtifacts} */ (id); - const artifact = await Promise.resolve() - .then(() => gatherer.instance.snapshot({gatherMode: 'snapshot', driver})) - .catch(err => err); - - artifacts[artifactName] = artifact; - } - - return /** @type {LH.Artifacts} */ ({...baseArtifacts, ...artifacts}); // Cast to drop Partial<> - }, - { - url, - config, - } - ); -} +const {snapshot} = require('./gather/snapshot-runner.js'); +const {startTimespan} = require('./gather/timespan-runner.js'); module.exports = { snapshot, + startTimespan, }; diff --git a/lighthouse-core/fraggle-rock/config/default-config.js b/lighthouse-core/fraggle-rock/config/default-config.js index ecb5332c9b56..8ab688cb005e 100644 --- a/lighthouse-core/fraggle-rock/config/default-config.js +++ b/lighthouse-core/fraggle-rock/config/default-config.js @@ -11,6 +11,7 @@ const legacyDefaultConfig = require('../../config/default-config.js'); const defaultConfig = { artifacts: [ {id: 'Accessibility', gatherer: 'accessibility'}, + {id: 'ConsoleMessages', gatherer: 'console-messages'}, ], settings: legacyDefaultConfig.settings, audits: legacyDefaultConfig.audits, diff --git a/lighthouse-core/fraggle-rock/gather/base-artifacts.js b/lighthouse-core/fraggle-rock/gather/base-artifacts.js new file mode 100644 index 000000000000..5ff65d1f0083 --- /dev/null +++ b/lighthouse-core/fraggle-rock/gather/base-artifacts.js @@ -0,0 +1,34 @@ +/** + * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +/** + * @param {LH.Config.FRConfig} config + * @return {LH.BaseArtifacts} + */ +function getBaseArtifacts(config) { + // TODO(FR-COMPAT): convert these to regular artifacts + + return { + fetchTime: new Date().toJSON(), + LighthouseRunWarnings: [], + URL: {requestedUrl: '', finalUrl: ''}, + Timing: [], + Stacks: [], + settings: config.settings, + HostFormFactor: 'mobile', + HostUserAgent: 'unknown', + NetworkUserAgent: 'unknown', + BenchmarkIndex: 0, + InstallabilityErrors: {errors: []}, + traces: {}, + devtoolsLogs: {}, + WebAppManifest: null, + PageLoadError: null, + }; +} + +module.exports = {getBaseArtifacts}; diff --git a/lighthouse-core/fraggle-rock/gather/base-gatherer.js b/lighthouse-core/fraggle-rock/gather/base-gatherer.js index 258808720f64..f245ef182ae8 100644 --- a/lighthouse-core/fraggle-rock/gather/base-gatherer.js +++ b/lighthouse-core/fraggle-rock/gather/base-gatherer.js @@ -26,6 +26,20 @@ class FRGatherer { */ snapshot(passContext) { } + /** + * Method to start observing a page for an arbitrary period of time. + * @param {LH.Gatherer.FRTransitionalContext} passContext + * @return {Promise|void} + */ + beforeTimespan(passContext) { } + + /** + * Method to end observing a page after an arbitrary period of time and return the results. + * @param {LH.Gatherer.FRTransitionalContext} passContext + * @return {LH.Gatherer.PhaseResult} + */ + afterTimespan(passContext) { } + /** * Legacy property used to define the artifact ID. In Fraggle Rock, the artifact ID lives on the config. * @return {keyof LH.GathererArtifacts} @@ -38,9 +52,11 @@ class FRGatherer { /** * Legacy method. Called before navigation to target url, roughly corresponds to `beforeTimespan`. * @param {LH.Gatherer.PassContext} passContext - * @return {LH.Gatherer.PhaseResult} + * @return {Promise} */ - beforePass(passContext) { } + async beforePass(passContext) { + await this.beforeTimespan(passContext); + } /** * Legacy method. Should never be used by a Fraggle Rock gatherer, here for compat only. @@ -53,9 +69,13 @@ class FRGatherer { * Legacy method. Roughly corresponds to `afterTimespan` or `snapshot` depending on type of gatherer. * @param {LH.Gatherer.PassContext} passContext * @param {LH.Gatherer.LoadData} loadData - * @return {LH.Gatherer.PhaseResult} + * @return {Promise} */ - afterPass(passContext, loadData) { + async afterPass(passContext, loadData) { + if (this.meta.supportedModes.includes('timespan')) { + return this.afterTimespan(passContext); + } + return this.snapshot(passContext); } } diff --git a/lighthouse-core/fraggle-rock/gather/snapshot-runner.js b/lighthouse-core/fraggle-rock/gather/snapshot-runner.js new file mode 100644 index 000000000000..772b6251d239 --- /dev/null +++ b/lighthouse-core/fraggle-rock/gather/snapshot-runner.js @@ -0,0 +1,50 @@ +/** + * @license Copyright 2020 The Lighthouse Authors. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +const Driver = require('./driver.js'); +const Runner = require('../../runner.js'); +const {initializeConfig} = require('../config/config.js'); +const {getBaseArtifacts} = require('./base-artifacts.js'); + +/** @param {{page: import('puppeteer').Page, config?: LH.Config.Json}} options */ +async function snapshot(options) { + const {config} = initializeConfig(options.config, {gatherMode: 'snapshot'}); + const driver = new Driver(options.page); + await driver.connect(); + + const url = await options.page.url(); + + return Runner.run( + async () => { + const baseArtifacts = getBaseArtifacts(config); + baseArtifacts.URL.requestedUrl = url; + baseArtifacts.URL.finalUrl = url; + + /** @type {Partial} */ + const artifacts = {}; + + for (const {id, gatherer} of config.artifacts || []) { + const artifactName = /** @type {keyof LH.GathererArtifacts} */ (id); + const artifact = await Promise.resolve() + .then(() => gatherer.instance.snapshot({gatherMode: 'snapshot', driver})) + .catch(err => err); + + artifacts[artifactName] = artifact; + } + + return /** @type {LH.Artifacts} */ ({...baseArtifacts, ...artifacts}); // Cast to drop Partial<> + }, + { + url, + config, + } + ); +} + +module.exports = { + snapshot, +}; diff --git a/lighthouse-core/fraggle-rock/gather/timespan-runner.js b/lighthouse-core/fraggle-rock/gather/timespan-runner.js new file mode 100644 index 000000000000..c21c64ac8c29 --- /dev/null +++ b/lighthouse-core/fraggle-rock/gather/timespan-runner.js @@ -0,0 +1,69 @@ +/** + * @license Copyright 2021 The Lighthouse Authors. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ +'use strict'; + +const Driver = require('./driver.js'); +const Runner = require('../../runner.js'); +const {initializeConfig} = require('../config/config.js'); +const {getBaseArtifacts} = require('./base-artifacts.js'); + +/** + * @param {{page: import('puppeteer').Page, config?: LH.Config.Json}} options + * @return {Promise<{endTimespan(): Promise}>} + */ +async function startTimespan(options) { + const {config} = initializeConfig(options.config, {gatherMode: 'timespan'}); + const driver = new Driver(options.page); + await driver.connect(); + + const requestedUrl = await options.page.url(); + + /** @type {Record>} */ + const artifactErrors = {}; + + for (const {id, gatherer} of config.artifacts || []) { + artifactErrors[id] = await Promise.resolve() + .then(() => gatherer.instance.beforeTimespan({gatherMode: 'timespan', driver})) + .catch(err => err); + } + + return { + async endTimespan() { + const finalUrl = await options.page.url(); + return Runner.run( + async () => { + const baseArtifacts = getBaseArtifacts(config); + baseArtifacts.URL.requestedUrl = requestedUrl; + baseArtifacts.URL.finalUrl = finalUrl; + + /** @type {Partial} */ + const artifacts = {}; + + for (const {id, gatherer} of config.artifacts || []) { + const artifactName = /** @type {keyof LH.GathererArtifacts} */ (id); + const artifact = artifactErrors[id] + ? Promise.reject(artifactErrors[id]) + : await Promise.resolve() + .then(() => gatherer.instance.afterTimespan({gatherMode: 'timespan', driver})) + .catch(err => err); + + artifacts[artifactName] = artifact; + } + + return /** @type {LH.Artifacts} */ ({...baseArtifacts, ...artifacts}); // Cast to drop Partial<> + }, + { + url: finalUrl, + config, + } + ); + }, + }; +} + +module.exports = { + startTimespan, +}; diff --git a/lighthouse-core/gather/gatherers/console-messages.js b/lighthouse-core/gather/gatherers/console-messages.js index 79c4b29fcf88..58c6e014d217 100644 --- a/lighthouse-core/gather/gatherers/console-messages.js +++ b/lighthouse-core/gather/gatherers/console-messages.js @@ -11,7 +11,7 @@ 'use strict'; -const Gatherer = require('./gatherer.js'); +const Gatherer = require('../../fraggle-rock/gather/base-gatherer.js'); /** * @param {LH.Crdp.Runtime.RemoteObject} obj @@ -30,7 +30,16 @@ function remoteObjectToString(obj) { return `[${type} ${className}]`; } +/** + * @implements {LH.Gatherer.GathererInstance} + * @implements {LH.Gatherer.FRGathererInstance} + */ class ConsoleMessages extends Gatherer { + /** @type {LH.Gatherer.GathererMeta} */ + meta = { + supportedModes: ['timespan', 'navigation'], + } + constructor() { super(); /** @type {LH.Artifacts.ConsoleMessage[]} */ @@ -120,33 +129,33 @@ class ConsoleMessages extends Gatherer { } /** - * @param {LH.Gatherer.PassContext} passContext + * @param {LH.Gatherer.FRTransitionalContext} passContext */ - async beforePass(passContext) { - const driver = passContext.driver; + async beforeTimespan(passContext) { + const session = passContext.driver.defaultSession; - driver.on('Log.entryAdded', this._onLogEntryAdded); - await driver.sendCommand('Log.enable'); - await driver.sendCommand('Log.startViolationsReport', { + session.on('Log.entryAdded', this._onLogEntryAdded); + await session.sendCommand('Log.enable'); + await session.sendCommand('Log.startViolationsReport', { config: [{name: 'discouragedAPIUse', threshold: -1}], }); - driver.on('Runtime.consoleAPICalled', this._onConsoleAPICalled); - driver.on('Runtime.exceptionThrown', this._onExceptionThrown); - await driver.sendCommand('Runtime.enable'); + session.on('Runtime.consoleAPICalled', this._onConsoleAPICalled); + session.on('Runtime.exceptionThrown', this._onExceptionThrown); + await session.sendCommand('Runtime.enable'); } /** - * @param {LH.Gatherer.PassContext} passContext + * @param {LH.Gatherer.FRTransitionalContext} passContext * @return {Promise} */ - async afterPass({driver}) { - await driver.sendCommand('Log.stopViolationsReport'); - await driver.off('Log.entryAdded', this._onLogEntryAdded); - await driver.sendCommand('Log.disable'); - await driver.off('Runtime.consoleAPICalled', this._onConsoleAPICalled); - await driver.off('Runtime.exceptionThrown', this._onExceptionThrown); - await driver.sendCommand('Runtime.disable'); + async afterTimespan({driver}) { + await driver.defaultSession.sendCommand('Log.stopViolationsReport'); + await driver.defaultSession.off('Log.entryAdded', this._onLogEntryAdded); + await driver.defaultSession.sendCommand('Log.disable'); + await driver.defaultSession.off('Runtime.consoleAPICalled', this._onConsoleAPICalled); + await driver.defaultSession.off('Runtime.exceptionThrown', this._onExceptionThrown); + await driver.defaultSession.sendCommand('Runtime.disable'); return this._logEntries; } } diff --git a/lighthouse-core/test/fixtures/fraggle-rock/snapshot-basic/onclick.html b/lighthouse-core/test/fixtures/fraggle-rock/snapshot-basic/onclick.html index b485190d538c..38cc54166e5e 100644 --- a/lighthouse-core/test/fixtures/fraggle-rock/snapshot-basic/onclick.html +++ b/lighthouse-core/test/fixtures/fraggle-rock/snapshot-basic/onclick.html @@ -32,8 +32,11 @@ document.addEventListener('click', () => { addTemplate('#violations'); + console.error('Accessibility violations added!'); }); + // Add the click target with JavaScript so when we `waitFor('#click-target')` we know that + // the listener has been installed too. addTemplate('#click-target'); diff --git a/lighthouse-core/test/fraggle-rock/api-test-pptr.js b/lighthouse-core/test/fraggle-rock/api-test-pptr.js index 7ce0a677f24a..175b2582d8df 100644 --- a/lighthouse-core/test/fraggle-rock/api-test-pptr.js +++ b/lighthouse-core/test/fraggle-rock/api-test-pptr.js @@ -14,6 +14,23 @@ const StaticServer = require('../../../lighthouse-cli/test/fixtures/static-serve jest.setTimeout(90_000); +/** + * @param {LH.Result} lhr + */ +function getAuditsBreakdown(lhr) { + const auditResults = Object.values(lhr.audits); + const irrelevantDisplayModes = new Set(['notApplicable', 'manual']); + const applicableAudits = auditResults.filter( + audit => !irrelevantDisplayModes.has(audit.scoreDisplayMode) + ); + + const erroredAudits = applicableAudits.filter(audit => audit.score === null); + + const failedAudits = applicableAudits.filter(audit => audit.score !== null && audit.score < 1); + + return {auditResults, erroredAudits, failedAudits}; +} + describe('Fraggle Rock API', () => { /** @type {InstanceType} */ let server; @@ -46,18 +63,22 @@ describe('Fraggle Rock API', () => { await server.close(); }); + async function setupTestPage() { + await page.goto(`${serverBaseUrl}/onclick.html`); + // Wait for the javascript to run. + await page.waitForSelector('button'); + await page.click('button'); + // Wait for the violations to appear (and console to be populated). + await page.waitForSelector('input'); + } + describe('snapshot', () => { beforeEach(() => { server.baseDir = path.join(__dirname, '../fixtures/fraggle-rock/snapshot-basic'); }); it('should compute accessibility results on the page as-is', async () => { - await page.goto(`${serverBaseUrl}/onclick.html`); - // Wait for the javascript to run - await page.waitForSelector('button'); - await page.click('button'); - // Wait for the violations to appear - await page.waitForSelector('input'); + await setupTestPage(); const result = await lighthouse.snapshot({page}); if (!result) throw new Error('Lighthouse failed to produce a result'); @@ -66,22 +87,49 @@ describe('Fraggle Rock API', () => { const accessibility = lhr.categories.accessibility; expect(accessibility.score).toBeLessThan(1); - const auditResults = Object.values(lhr.audits); + const {auditResults, erroredAudits, failedAudits} = getAuditsBreakdown(lhr); // TODO(FR-COMPAT): This assertion can be removed when full compatibility is reached. expect(auditResults.length).toMatchInlineSnapshot(`58`); - const irrelevantDisplayModes = new Set(['notApplicable', 'manual']); - const applicableAudits = auditResults.filter( - audit => !irrelevantDisplayModes.has(audit.scoreDisplayMode) - ); - - const erroredAudits = applicableAudits.filter(audit => audit.score === null); expect(erroredAudits).toHaveLength(0); + expect(failedAudits.map(audit => audit.id)).toContain('label'); + }); + }); + + describe('startTimespan', () => { + beforeEach(() => { + server.baseDir = path.join(__dirname, '../fixtures/fraggle-rock/snapshot-basic'); + }); + + it('should compute ConsoleMessage results across a span of time', async () => { + const run = await lighthouse.startTimespan({page}); + + await setupTestPage(); + + const result = await run.endTimespan(); + if (!result) throw new Error('Lighthouse failed to produce a result'); + + const {lhr} = result; + const bestPractices = lhr.categories['best-practices']; + expect(bestPractices.score).toBeLessThan(1); - const failedAuditIds = applicableAudits - .filter(audit => audit.score !== null && audit.score < 1) - .map(audit => audit.id); - expect(failedAuditIds).toContain('label'); + const {erroredAudits, failedAudits} = getAuditsBreakdown(lhr); + + expect(erroredAudits).toHaveLength(0); + expect(failedAudits.map(audit => audit.id)).toContain('errors-in-console'); + + const errorsInConsole = lhr.audits['errors-in-console']; + if (!errorsInConsole.details) throw new Error('Error in consoles audit missing details'); + if (errorsInConsole.details.type !== 'table') throw new Error('Unexpected details'); + const errorLogs = errorsInConsole.details.items; + const matchingLog = errorLogs.find( + log => + log.source === 'console.error' && + String(log.description || '').includes('violations added') + ); + // If we couldn't find it, assert something similar on the object that we know will fail + // for a better debug message. + if (!matchingLog) expect(errorLogs).toContain({description: /violations added/}); }); }); }); diff --git a/lighthouse-core/test/fraggle-rock/gather/base-gatherer-test.js b/lighthouse-core/test/fraggle-rock/gather/base-gatherer-test.js index 6a9ca6bab9d9..78e9715cb9b0 100644 --- a/lighthouse-core/test/fraggle-rock/gather/base-gatherer-test.js +++ b/lighthouse-core/test/fraggle-rock/gather/base-gatherer-test.js @@ -13,7 +13,7 @@ const Gatherer = require('../../../fraggle-rock/gather/base-gatherer.js'); const fakeParam = {}; describe('BaseGatherer', () => { - it('should fullfill the contract of both interfaces', () => { + it('should fullfill the contract of both interfaces', async () => { const gatherer = new Gatherer(); // Fraggle Rock Gatherer contract @@ -22,13 +22,25 @@ describe('BaseGatherer', () => { // Legacy Gatherer contract expect(typeof gatherer.name).toBe('string'); - expect(gatherer.beforePass(fakeParam)).toBe(undefined); - expect(gatherer.pass(fakeParam)).toBe(undefined); - expect(gatherer.afterPass(fakeParam, fakeParam)).toBe(undefined); + expect(await gatherer.beforePass(fakeParam)).toBe(undefined); + expect(await gatherer.pass(fakeParam)).toBe(undefined); + expect(await gatherer.afterPass(fakeParam, fakeParam)).toBe(undefined); + }); + + describe('.beforePass', () => { + it('delegates to beforeTimespan by default', async () => { + class MyGatherer extends Gatherer { + beforeTimespan = jest.fn() + } + + const gatherer = new MyGatherer(); + await gatherer.beforePass(fakeParam); + expect(gatherer.beforeTimespan).toHaveBeenCalledWith(fakeParam); + }); }); describe('.afterPass', () => { - it('delegates to snapshot', () => { + it('delegates to snapshot by default', async () => { class MyGatherer extends Gatherer { /** @param {*} _ */ snapshot(_) { @@ -38,7 +50,27 @@ describe('BaseGatherer', () => { const gatherer = new MyGatherer(); expect(gatherer.snapshot(fakeParam)).toEqual('Hello, Fraggle!'); - expect(gatherer.afterPass(fakeParam, fakeParam)).toEqual('Hello, Fraggle!'); + expect(await gatherer.afterPass(fakeParam, fakeParam)).toEqual('Hello, Fraggle!'); + }); + + it('delegates to afterTimespan when supported', async () => { + class MyGatherer extends Gatherer { + /** @type {LH.Gatherer.GathererMeta} */ + meta = {supportedModes: ['timespan']}; + + /** @param {*} _ */ + snapshot(_) { + return 'Oops, wrong method!'; + } + + /** @param {*} _ */ + afterTimespan(_) { + return 'Hello, Fraggle!'; + } + } + + const gatherer = new MyGatherer(); + expect(await gatherer.afterPass(fakeParam, fakeParam)).toEqual('Hello, Fraggle!'); }); }); }); diff --git a/lighthouse-core/test/gather/gatherers/console-messages-test.js b/lighthouse-core/test/gather/gatherers/console-messages-test.js index e0d8bcbf4a4e..31487a3f4d35 100644 --- a/lighthouse-core/test/gather/gatherers/console-messages-test.js +++ b/lighthouse-core/test/gather/gatherers/console-messages-test.js @@ -10,7 +10,7 @@ const ConsoleMessagesGatherer = require('../../../gather/gatherers/console-messages.js'); const assert = require('assert').strict; -class MockDriver { +class MockSession { constructor() { this.listeners = new Map(); } @@ -30,6 +30,10 @@ class MockDriver { } } +class MockDriver { + defaultSession = new MockSession +} + describe('ConsoleMessages', () => { it('captures the exceptions raised', async () => { const consoleGatherer = new ConsoleMessagesGatherer(); @@ -61,7 +65,7 @@ describe('ConsoleMessages', () => { const options = {driver}; await consoleGatherer.beforePass(options); - driver.fireForTest('Runtime.exceptionThrown', runtimeEx); + driver.defaultSession.fireForTest('Runtime.exceptionThrown', runtimeEx); const artifact = await consoleGatherer.afterPass(options); @@ -103,7 +107,7 @@ describe('ConsoleMessages', () => { const options = {driver}; await consoleGatherer.beforePass(options); - driver.fireForTest('Runtime.consoleAPICalled', consoleWarnEvent); + driver.defaultSession.fireForTest('Runtime.consoleAPICalled', consoleWarnEvent); const artifact = await consoleGatherer.afterPass(options); @@ -135,7 +139,7 @@ describe('ConsoleMessages', () => { const options = {driver}; await consoleGatherer.beforePass(options); - driver.fireForTest('Runtime.consoleAPICalled', consoleWarnEvent); + driver.defaultSession.fireForTest('Runtime.consoleAPICalled', consoleWarnEvent); const artifact = await consoleGatherer.afterPass(options); @@ -259,7 +263,7 @@ describe('ConsoleMessages', () => { const options = {driver}; await consoleGatherer.beforePass(options); - driver.fireForTest('Runtime.consoleAPICalled', consoleWarnEvent); + driver.defaultSession.fireForTest('Runtime.consoleAPICalled', consoleWarnEvent); const artifact = await consoleGatherer.afterPass(options); @@ -317,7 +321,7 @@ describe('ConsoleMessages', () => { const options = {driver}; await consoleGatherer.beforePass(options); - driver.fireForTest('Runtime.consoleAPICalled', consoleErrorEvent); + driver.defaultSession.fireForTest('Runtime.consoleAPICalled', consoleErrorEvent); const artifact = await consoleGatherer.afterPass(options); @@ -357,7 +361,7 @@ describe('ConsoleMessages', () => { const options = {driver}; await consoleGatherer.beforePass(options); - driver.fireForTest('Runtime.consoleAPICalled', consoleLog); + driver.defaultSession.fireForTest('Runtime.consoleAPICalled', consoleLog); const artifact = await consoleGatherer.afterPass(options); @@ -405,8 +409,8 @@ describe('ConsoleMessages', () => { const options = {driver}; await consoleGatherer.beforePass(options); - driver.fireForTest('Log.entryAdded', logEntries[0]); - driver.fireForTest('Log.entryAdded', logEntries[1]); + driver.defaultSession.fireForTest('Log.entryAdded', logEntries[0]); + driver.defaultSession.fireForTest('Log.entryAdded', logEntries[1]); const artifact = await consoleGatherer.afterPass(options); diff --git a/types/gatherer.d.ts b/types/gatherer.d.ts index 9dc2b9919abe..ea1a71664803 100644 --- a/types/gatherer.d.ts +++ b/types/gatherer.d.ts @@ -53,8 +53,8 @@ declare global { trace?: Trace; } - type PhaseResult_ = void|LH.GathererArtifacts[keyof LH.GathererArtifacts] - export type PhaseResult = PhaseResult_ | Promise + export type PhaseResultNonPromise = void|LH.GathererArtifacts[keyof LH.GathererArtifacts] + export type PhaseResult = PhaseResultNonPromise | Promise export type GatherMode = 'snapshot'|'timespan'|'navigation'; @@ -73,6 +73,8 @@ declare global { name: keyof LH.GathererArtifacts; // temporary COMPAT measure until artifact config support is available meta: GathererMeta; snapshot(context: FRTransitionalContext): PhaseResult; + beforeTimespan(context: FRTransitionalContext): Promise|void; + afterTimespan(context: FRTransitionalContext): PhaseResult; } namespace Simulation {