Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// Add gatherer options to the passContext.
passContext.options = gathererDefn.options || {};
// If there was a pageLoadError, fail every afterPass with it rather than bail completely.
const artifactPromise = pageLoadError ?
Promise.reject(pageLoadError) :
// Wrap gatherer response in promise, whether rejected or not.
Promise.resolve().then(_ => gatherer.afterPass(passContext, passData));
const gathererResult = gathererResults[gatherer.name] || [];
gathererResult.push(artifactPromise);
gathererResults[gatherer.name] = gathererResult;
await artifactPromise.catch(() => {});
log.timeEnd(status);
}
log.timeEnd(apStatus);
// Resolve on tracing data using passName from config.
return passData;
}
async getBrowserVersion() {
const status = {msg: 'Getting browser version', id: 'lh:gather:getVersion'};
log.time(status, 'verbose');
const version = await this.sendCommand('Browser.getVersion');
const match = version.product.match(/\/(\d+)/); // eg 'Chrome/71.0.3577.0'
const milestone = match ? parseInt(match[1]) : 0;
log.timeEnd(status);
return Object.assign(version, {milestone});
}
for (const gathererDefn of passContext.passConfig.gatherers) {
const gatherer = gathererDefn.instance;
// Abuse the passContext to pass through gatherer options
passContext.options = gathererDefn.options || {};
const status = {
msg: `Retrieving setup: ${gatherer.name}`,
id: `lh:gather:beforePass:${gatherer.name}`,
};
log.time(status, 'verbose');
const artifactPromise = Promise.resolve().then(_ => gatherer.beforePass(passContext));
gathererResults[gatherer.name] = [artifactPromise];
await artifactPromise.catch(() => {});
log.timeEnd(status);
}
log.timeEnd(bpStatus);
}
async getBrowserVersion() {
const status = {msg: 'Getting browser version', id: 'lh:gather:getVersion'};
log.time(status, 'verbose');
const version = await this.sendCommand('Browser.getVersion');
const match = version.product.match(/\/(\d+)/); // eg 'Chrome/71.0.3577.0'
const milestone = match ? parseInt(match[1]) : 0;
log.timeEnd(status);
return Object.assign(version, {milestone});
}
static async beginRecording(passContext) {
const status = {msg: 'Beginning devtoolsLog and trace', id: 'lh:gather:beginRecording'};
log.time(status);
const {driver, passConfig, settings} = passContext;
// Always record devtoolsLog
await driver.beginDevtoolsLog();
if (passConfig.recordTrace) {
await driver.beginTrace(settings);
}
log.timeEnd(status);
}
/** @type {?Array} */
this.audits = Config.requireAudits(configJSON.audits, configDir);
/** @type {?Record} */
this.categories = configJSON.categories || null;
/** @type {?Record} */
this.groups = configJSON.groups || null;
Config.filterConfigIfNeeded(this);
assertValidPasses(this.passes, this.audits);
assertValidCategories(this.categories, this.audits, this.groups);
// TODO(bckenny): until tsc adds @implements support, assert that Config is a ConfigJson.
/** @type {LH.Config.Json} */
const configJson = this; // eslint-disable-line no-unused-vars
log.timeEnd(status);
}
/** @type {?Array} */
this.audits = Config.requireAudits(configJSON.audits, configDir);
/** @type {?Record} */
this.categories = configJSON.categories || null;
/** @type {?Record} */
this.groups = configJSON.groups || null;
Config.filterConfigIfNeeded(this);
validatePasses(this.passes, this.audits);
validateCategories(this.categories, this.audits, this.groups);
// TODO(bckenny): until tsc adds @implements support, assert that Config is a ConfigJson.
/** @type {LH.Config.Json} */
const configJson = this; // eslint-disable-line no-unused-vars
log.timeEnd(status);
}
for (const gathererDefn of passContext.passConfig.gatherers) {
const gatherer = gathererDefn.instance;
// Abuse the passContext to pass through gatherer options
passContext.options = gathererDefn.options || {};
const status = {
msg: `Gathering setup: ${gatherer.name}`,
id: `lh:gather:beforePass:${gatherer.name}`,
};
log.time(status, 'verbose');
const artifactPromise = Promise.resolve().then(_ => gatherer.beforePass(passContext));
gathererResults[gatherer.name] = [artifactPromise];
await artifactPromise.catch(() => {});
log.timeEnd(status);
}
log.timeEnd(bpStatus);
}
};
} else if (gathererDefn.path) {
const path = gathererDefn.path;
const options = gathererDefn.options;
return Config.requireGathererFromPath(path, options, coreList, configDir);
} else {
throw new Error('Invalid expanded Gatherer: ' + JSON.stringify(gathererDefn));
}
});
const mergedDefns = mergeOptionsOfItems(gathererDefns);
mergedDefns.forEach(gatherer => assertValidGatherer(gatherer.instance, gatherer.path));
return Object.assign(pass, {gatherers: mergedDefns});
});
log.timeEnd(status);
return fullPasses;
}
static async setupDriver(driver, options) {
const status = {msg: 'Initializing…', id: 'lh:gather:setupDriver'};
log.time(status);
const resetStorage = !options.settings.disableStorageReset;
await driver.assertNoSameOriginServiceWorkerClients(options.requestedUrl);
await driver.beginEmulation(options.settings);
await driver.enableRuntimeEvents();
await driver.enableAsyncStacks();
await driver.cacheNatives();
await driver.registerPerformanceObserver();
await driver.dismissJavaScriptDialogs();
if (resetStorage) await driver.clearDataForOrigin(options.requestedUrl);
log.timeEnd(status);
}