UNPKG

sitespeed.io

Version:

Analyze the web performance of your site

188 lines (173 loc) 5.6 kB
#!/usr/bin/env node 'use strict'; const yargs = require('yargs'); const browsertime = require('browsertime'); const merge = require('lodash.merge'); const getURLs = require('../lib/cli/util').getURLs; const get = require('lodash.get'); const set = require('lodash.set'); const findUp = require('find-up'); const fs = require('fs'); const browsertimeConfig = require('../lib/plugins/browsertime/index').config; const iphone6UserAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 ' + '(KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25'; const configPath = findUp.sync(['.sitespeed.io.json']); let config; try { config = configPath ? JSON.parse(fs.readFileSync(configPath)) : {}; } catch (e) { if (e instanceof SyntaxError) { /* eslint no-console: off */ console.error( 'Could not parse the config JSON file ' + configPath + '. Is the file really valid JSON?' ); } throw e; } async function testURLs(engine, urls) { try { await engine.start(); for (let url of urls) { const result = await engine.run(url); for (let errors of result[0].errors) { if (errors.length > 0) { process.exitCode = 1; } } } } finally { engine.stop(); } } async function runBrowsertime() { let parsed = yargs .env('SITESPEED_IO') .require(1, 'urlOrFile') .option('browsertime.browser', { alias: ['b', 'browser'], default: browsertimeConfig.browser, describe: 'Choose which Browser to use when you test.', choices: ['chrome', 'firefox'], group: 'Browser' }) .option('mobile', { describe: 'Access pages as mobile a fake mobile device. Set UA and width/height. For Chrome it will use device Apple iPhone 6.', default: false, type: 'boolean' }) .option('browsertime.pageCompleteCheckPollTimeout', { alias: 'pageCompleteCheckPollTimeout', type: 'number', default: 200, describe: 'The time in ms to wait for running the page complete check the next time.' }) .option('browsertime.pageCompleteCheckStartWait', { alias: 'pageCompleteCheckStartWait', type: 'number', default: 500, describe: 'The time in ms to wait for running the page complete check for the first time. Use this when you have a pageLoadStrategy set to none' }) .option('browsertime.pageLoadStrategy', { alias: 'pageLoadStrategy', type: 'string', default: 'normal', choices: ['eager', 'none', 'normal'], describe: 'Set the strategy to waiting for document readiness after a navigation event. After the strategy is ready, your pageCompleteCheck will start runninhg. This only for Firefox and Chrome and please check which value each browser implements.' }) .option('browsertime.cpu', { alias: 'cpu', type: 'boolean', describe: 'Easy way to enable both chrome.timeline and CPU long tasks.', group: 'chrome' }) .option('browsertime.chrome.CPUThrottlingRate', { alias: 'chrome.CPUThrottlingRate', type: 'number', describe: 'Enables CPU throttling to emulate slow CPUs. Throttling rate as a slowdown factor (1 is no throttle, 2 is 2x slowdown, etc)', group: 'chrome' }) .option('config', { describe: 'Path to JSON config file. You can also use a .browsertime.json file that will automatically be found by Browsertime using find-up.', config: 'config' }) .option('browsertime.viewPort', { alias: 'viewPort', default: browsertimeConfig.viewPort, describe: 'The browser view port size WidthxHeight like 400x300', group: 'Browser' }) .option('browsertime.android', { alias: 'android', type: 'boolean', default: false, describe: 'Short key to use Android. Will automatically use com.android.chrome for Chrome and stable Firefox. If you want to use another Chrome version, use --chrome.android.package' }) .config(config); const defaultConfig = { iterations: 1, connectivity: { profile: 'native', downstreamKbps: undefined, upstreamKbps: undefined, latency: undefined, engine: 'external' }, viewPort: '1366x708', delay: 0, video: false, visualMetrics: false, resultDir: '/tmp/browsertime', chrome: { ignoreCertificateErrors: true } }; const btOptions = merge({}, parsed.argv.browsertime, defaultConfig); browsertime.logging.configure(parsed.argv); // We have a special hack in sitespeed.io when you set --mobile if (parsed.argv.mobile) { btOptions.viewPort = '360x640'; btOptions['view-port'] = '360x640'; if (btOptions.browser === 'chrome') { const emulation = get( btOptions, 'chrome.mobileEmulation.deviceName', 'Moto G4' ); btOptions.chrome.mobileEmulation = { deviceName: emulation }; } else { btOptions.userAgent = iphone6UserAgent; } } if (parsed.argv.android) { if (parsed.argv.browser === 'chrome') { // Default to Chrome Android. set( btOptions, 'chrome.android.package', get(btOptions, 'chrome.android.package', 'com.android.chrome') ); } } const engine = new browsertime.Engine(btOptions); const urls = getURLs(parsed.argv._); try { await testURLs(engine, urls); } catch (e) { console.error('Could not run ' + e); process.exit(1); } process.exit(); } runBrowsertime();