browsertime
Version:
Get performance metrics from your web page using Browsertime.
231 lines (205 loc) • 7.83 kB
JavaScript
import { readFileSync } from 'node:fs';
import intel from 'intel';
import { chromeDesktopOptions as defaultChromeOptions } from '../settings/chromeDesktopOptions.js';
import { chromeAndroidOptions as defaultAndroidChromeOptions } from '../settings/chromeAndroidOptions.js';
import { getViewPort } from '../../support/getViewPort.js';
import { toArray } from '../../support/util.js';
import { isAndroidConfigured } from '../../android/index.js';
const log = intel.getLogger('browsertime.chrome');
const CHROME_AMD_EDGE_INTERNAL_PHONE_HOME = [
'MAP cache.pack.google.com 127.0.0.1',
'MAP clients1.google.com 127.0.0.1',
'MAP update.googleapis.com 127.0.0.1',
'MAP content-autofill.googleapis.com 127.0.0.1',
'MAP redirector.gvt1.com 127.0.0.1',
'MAP laptop-updates.brave.com 127.0.0.1',
'MAP offlinepages-pa.googleapis.com 127.0.0.1',
'MAP edge.microsoft.com 127.0.0.1',
'MAP optimizationguide-pa.googleapis.com 127.0.0.1'
];
const CHROME_FEATURES_THAT_WE_DISABLES = [
'AutofillServerCommunication',
'CalculateNativeWinOcclusion',
'HeavyAdPrivacyMitigations',
'InterestFeedContentSuggestions',
'MediaRouter',
'OfflinePagesPrefetching',
'OptimizationHints',
'SidePanelPinning',
'Translate',
'msAutofillEdgeCoupons',
'msShoppingTrigger',
'msEdgeShoppingUI',
'msEntityExtraction',
'msEntityExtractionProactive',
'msWebAssist'
];
export function setupChromiumOptions(
seleniumOptions,
browserOptions,
options,
baseDir
) {
// Fixing save password popup, only on Desktop
if (!isAndroidConfigured(options)) {
seleniumOptions.setUserPreferences({
'profile.password_manager_enable': false,
'profile.default_content_setting_values.notifications': 2,
credentials_enable_service: false
});
}
if (options.headless) {
seleniumOptions.addArguments('--headless=new');
}
// If we run in Docker we need to always use no-sandbox
if (options.docker) {
seleniumOptions.addArguments('--no-sandbox');
seleniumOptions.addArguments('--disable-setuid-sandbox');
}
if (options.xvfb && (options.xvfb === true || options.xvfb === 'true')) {
seleniumOptions.addArguments('--disable-gpu');
}
seleniumOptions.addArguments(
'--disable-features=' + CHROME_FEATURES_THAT_WE_DISABLES.join(',')
);
const viewPort = getViewPort(options);
// If viewport is defined (only on desktop) then set start args
if (viewPort) {
seleniumOptions.addArguments('--window-position=0,0');
seleniumOptions.addArguments('--window-size=' + viewPort.replace('x', ','));
}
// If we are recording responses and we also block on domain
if (
browserOptions.blockDomainsExcept &&
browserOptions.webPageReplayHostResolver &&
browserOptions.webPageReplayRecord
) {
const firstPartyDomains = toArray(browserOptions.blockDomainsExcept);
let excludes = '';
for (let domain of firstPartyDomains) {
excludes += ` MAP ${domain}:80 127.0.0.1:${browserOptions.webPageReplayHTTPPort},`;
excludes += ` MAP ${domain}:443 127.0.0.1:${browserOptions.webPageReplayHTTPSPort},`;
}
excludes += ' EXCLUDE localhost';
seleniumOptions.addArguments('--host-resolver-rules=' + excludes);
} // If we are replaying with WebPageReplay
else if (browserOptions.webPageReplayHostResolver) {
seleniumOptions.addArguments(
`--host-resolver-rules= "MAP *:80 127.0.0.1:${browserOptions.webPageReplayHTTPPort}, MAP *:443 127.0.0.1:${browserOptions.webPageReplayHTTPSPort}, EXCLUDE localhost"`
);
} // If we do not use WebPageReplay but wanna block on domain
else if (browserOptions.blockDomainsExcept) {
let excludes = '';
let excludesDomains = toArray(browserOptions.blockDomainsExcept);
for (let domain of excludesDomains) {
excludes += 'MAP * 127.0.0.1, EXCLUDE ' + domain + ',';
}
seleniumOptions.addArguments('--host-resolver-rules=' + excludes);
} else {
// Make sure we only set this if we do not have any other host resolver rules
const chromeCommandLineArguments = toArray(browserOptions.args);
const argumentsWithHostResolverRules = chromeCommandLineArguments.filter(
argument => argument.includes('host-resolver-rules')
);
if (argumentsWithHostResolverRules.length === 0) {
seleniumOptions.addArguments(
`--host-resolver-rules="${CHROME_AMD_EDGE_INTERNAL_PHONE_HOME.join(
','
)}"`
);
}
}
if (options.extension) {
const extensions = Array.isArray(options.extension)
? options.extension
: [options.extension];
for (const extension of extensions) {
seleniumOptions.addExtensions(
readFileSync(extension, { encoding: 'base64' })
);
}
}
if (options.debug) {
seleniumOptions.addArguments('--auto-open-devtools-for-tabs');
}
const perfLogConfig = { enableNetwork: true, enablePage: true };
seleniumOptions.setPerfLoggingPrefs(perfLogConfig);
if (options.userAgent) {
seleniumOptions.addArguments('--user-agent=' + options.userAgent);
}
if (browserOptions.ignoreCertificateErrors) {
seleniumOptions.addArguments('--ignore-certificate-errors');
}
if (browserOptions.collectNetLog) {
const dir = isAndroidConfigured(browserOptions)
? '/data/local/tmp'
: baseDir;
seleniumOptions.addArguments(`--log-net-log=${dir}/chromeNetlog.json`);
const level = browserOptions.netLogCaptureMode || 'IncludeSensitive';
seleniumOptions.addArguments(`--net-log-capture-mode=${level}`);
}
if (browserOptions.android) {
seleniumOptions.addArguments(defaultAndroidChromeOptions);
seleniumOptions.addArguments(
'--remote-debugging-port=' + options.devToolsPort
);
} else {
if (browserOptions.noDefaultOptions) {
log.info('Skip setting default options for Chrome');
} else {
seleniumOptions.addArguments(defaultChromeOptions);
seleniumOptions.addArguments(
'--remote-debugging-port=' + options.devToolsPort
);
}
}
if (browserOptions.enableVideoAutoplay) {
seleniumOptions.addArguments('--autoplay-policy=no-user-gesture-required');
}
// It's a new splash screen introduced in Chrome 98
// for new profiles
// disable it with ChromeWhatsNewUI
if (browserOptions.args) {
const chromeCommandLineArguments = toArray(browserOptions.args);
for (const argument of chromeCommandLineArguments) {
if (
argument.includes('disable-features') &&
!argument.includes('ChromeWhatsNewUI')
) {
seleniumOptions.addArguments(`${argument},ChromeWhatsNewUI`);
log.debug('Set Chrome args %j', `${argument},ChromeWhatsNewUI`);
} else {
seleniumOptions.addArguments(argument);
log.debug('Set Chrome args %j', argument);
}
}
} else {
seleniumOptions.addArguments('--disable-features=ChromeWhatsNewUI');
}
if (browserOptions.binaryPath) {
seleniumOptions.setChromeBinaryPath(browserOptions.binaryPath);
}
if (browserOptions.mobileEmulation) {
seleniumOptions.setMobileEmulation(browserOptions.mobileEmulation);
}
// See https://bugs.chromium.org/p/chromium/issues/detail?id=818483
// Coming again in Chrome 76
seleniumOptions.excludeSwitches('enable-automation');
const android = browserOptions.android;
if (android) {
if (android.package) {
seleniumOptions.androidPackage(android.package);
if (android.activity) {
seleniumOptions.androidActivity(android.activity);
if (android.process) {
seleniumOptions.androidProcess(android.process);
}
}
} else {
seleniumOptions.androidChrome();
}
seleniumOptions.androidDeviceSerial(android.deviceSerial);
}
log.debug('Setting the following Selenium options: %j', seleniumOptions);
return seleniumOptions;
}