browsertime 14.4.0 → 14.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/bin/browsertime.js +1 -1
  3. package/lib/android/index.js +1 -1
  4. package/lib/chrome/har.js +4 -4
  5. package/lib/chrome/longTaskMetrics.js +1 -1
  6. package/lib/chrome/speedline.js +2 -2
  7. package/lib/chrome/webdriver/builder.js +1 -1
  8. package/lib/chrome/webdriver/setupChromiumOptions.js +7 -2
  9. package/lib/connectivity/trafficShapeParser.js +2 -2
  10. package/lib/connectivity/tsProxy.js +3 -3
  11. package/lib/core/engine/command/measure.js +16 -10
  12. package/lib/core/engine/command/mouse/clickAndHold.js +146 -0
  13. package/lib/core/engine/command/mouse/contextClick.js +61 -0
  14. package/lib/core/engine/command/mouse/doubleClick.js +76 -0
  15. package/lib/core/engine/command/mouse/index.js +9 -0
  16. package/lib/core/engine/command/mouse/mouseMove.js +81 -0
  17. package/lib/core/engine/command/mouse/singleClick.js +79 -0
  18. package/lib/core/engine/command/switch.js +2 -8
  19. package/lib/core/engine/iteration.js +5 -6
  20. package/lib/core/engine/run.js +2 -2
  21. package/lib/core/seleniumRunner.js +23 -22
  22. package/lib/core/webdriver/index.js +1 -1
  23. package/lib/edge/webdriver/builder.js +1 -1
  24. package/lib/extensionserver/setup.js +1 -1
  25. package/lib/firefox/geckoProfiler.js +2 -3
  26. package/lib/firefox/getHAR.js +1 -1
  27. package/lib/firefox/webdriver/builder.js +12 -7
  28. package/lib/firefox/webdriver/firefox.js +6 -7
  29. package/lib/safari/webdriver/builder.js +1 -1
  30. package/lib/support/browserScript.js +1 -1
  31. package/lib/support/cli.js +12 -0
  32. package/lib/support/engineUtils.js +1 -1
  33. package/lib/support/getViewPort.js +1 -1
  34. package/lib/support/har/index.js +13 -14
  35. package/lib/support/pathToFolder.js +4 -10
  36. package/lib/support/preURL.js +1 -1
  37. package/lib/support/setResourceTimingBufferSize.js +1 -1
  38. package/lib/support/statistics.js +1 -1
  39. package/lib/support/stop.js +1 -1
  40. package/lib/support/storageManager.js +5 -10
  41. package/lib/video/postprocessing/finetune/addTextToVideo.js +1 -1
  42. package/lib/video/postprocessing/finetune/convertFps.js +1 -1
  43. package/lib/video/postprocessing/finetune/getFont.js +1 -1
  44. package/lib/video/postprocessing/finetune/getTimingMetrics.js +5 -4
  45. package/lib/video/postprocessing/finetune/index.js +1 -1
  46. package/lib/video/postprocessing/finetune/removeOrange.js +1 -1
  47. package/lib/video/postprocessing/visualmetrics/extraMetrics.js +1 -1
  48. package/lib/video/postprocessing/visualmetrics/getVideoMetrics.js +1 -1
  49. package/lib/video/screenRecording/desktop/ffmpegRecorder.js +3 -3
  50. package/lib/video/screenRecording/desktop/osx/getSPDisplaysDataType.js +1 -1
  51. package/lib/video/screenRecording/desktop/osx/getScreen.js +1 -1
  52. package/lib/video/screenRecording/firefox/firefoxWindowRecorder.js +2 -2
  53. package/lib/video/screenRecording/setOrangeBackground.js +1 -1
  54. package/package.json +9 -9
  55. package/lib/core/engine/command/mouse.js +0 -314
@@ -0,0 +1,79 @@
1
+ 'use strict';
2
+
3
+ const log = require('intel').getLogger('browsertime.command.mouse');
4
+ const webdriver = require('selenium-webdriver');
5
+
6
+ class SingleClick {
7
+ constructor(browser, pageCompleteCheck) {
8
+ this.browser = browser;
9
+ this.actions = this.browser.getDriver().actions({ async: true });
10
+ this.pageCompleteCheck = pageCompleteCheck;
11
+ }
12
+
13
+ /**
14
+ * Perform mouse single click on an element matches a XPath selector.
15
+ * @param {string} xpath
16
+ * @returns {Promise} Promise object represents when the element has been clicked.
17
+ * @throws Will throw an error if the element is not found.
18
+ */
19
+ async byXpath(xpath, options) {
20
+ try {
21
+ const element = await this.browser
22
+ .getDriver()
23
+ .findElement(webdriver.By.xpath(xpath));
24
+ await this.actions.click(element).perform();
25
+ if (options && 'wait' in options && options.wait === true) {
26
+ return this.browser.extraWait(this.pageCompleteCheck);
27
+ }
28
+ } catch (e) {
29
+ log.error('Could not single click on element with xpath %s', xpath);
30
+ log.verbose(e);
31
+ throw Error('Could not single click on element with xpath ' + xpath);
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Perform mouse single click on an element matches a CSS selector.
37
+ * @param {string} selector
38
+ * @returns {Promise} Promise object represents when the element has been clicked.
39
+ * @throws Will throw an error if the element is not found.
40
+ */
41
+ async bySelector(selector, options) {
42
+ try {
43
+ const element = await this.browser
44
+ .getDriver()
45
+ .findElement(webdriver.By.css(selector));
46
+ await this.actions.click(element).perform();
47
+ if (options && 'wait' in options && options.wait === true) {
48
+ return this.browser.extraWait(this.pageCompleteCheck);
49
+ }
50
+ } catch (e) {
51
+ log.error('Could not single click on element with selector %s', selector);
52
+ log.verbose(e);
53
+ throw Error(
54
+ 'Could not single click on element with selector ' + selector
55
+ );
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Perform mouse single click at the cursor's position.
61
+ * @param {string} xpath
62
+ * @returns {Promise} Promise object represents when double click occurs.
63
+ * @throws Will throw an error if double click cannot be performed.
64
+ */
65
+ async atCursor(options) {
66
+ try {
67
+ await this.actions.click().perform();
68
+ if (options && 'wait' in options && options.wait === true) {
69
+ return this.browser.extraWait(this.pageCompleteCheck);
70
+ }
71
+ } catch (e) {
72
+ log.error('Could not perform single click');
73
+ log.verbose(e);
74
+ throw Error('Could not perform single click');
75
+ }
76
+ }
77
+ }
78
+
79
+ module.exports = SingleClick;
@@ -58,10 +58,7 @@ class Switch {
58
58
  */
59
59
  async toNewTab(url) {
60
60
  try {
61
- await this.browser
62
- .getDriver()
63
- .switchTo()
64
- .newWindow('tab');
61
+ await this.browser.getDriver().switchTo().newWindow('tab');
65
62
  if (url) {
66
63
  await this.navigate(url);
67
64
  await this.browser.extraWait(this.pageCompleteCheck);
@@ -80,10 +77,7 @@ class Switch {
80
77
  */
81
78
  async toNewWindow(url) {
82
79
  try {
83
- await this.browser
84
- .getDriver()
85
- .switchTo()
86
- .newWindow('window');
80
+ await this.browser.getDriver().switchTo().newWindow('window');
87
81
  if (url) {
88
82
  await this.navigate(url);
89
83
  await this.browser.extraWait(this.pageCompleteCheck);
@@ -31,7 +31,7 @@ const {
31
31
  ClickAndHold,
32
32
  ContextClick,
33
33
  MouseMove
34
- } = require('./command/mouse');
34
+ } = require('./command/mouse/');
35
35
 
36
36
  const { isAndroidConfigured, Android } = require('../../android');
37
37
  const Scroll = require('./command/scroll');
@@ -262,11 +262,10 @@ class Iteration {
262
262
  'PerceptualSpeedIndexProgress'
263
263
  ]) {
264
264
  if (videoMetrics.visualMetrics[progress]) {
265
- videoMetrics.visualMetrics[
266
- progress
267
- ] = util.jsonifyVisualProgress(
268
- videoMetrics.visualMetrics[progress]
269
- );
265
+ videoMetrics.visualMetrics[progress] =
266
+ util.jsonifyVisualProgress(
267
+ videoMetrics.visualMetrics[progress]
268
+ );
270
269
  }
271
270
  }
272
271
  result[i].videoRecordingStart = videoMetrics.videoRecordingStart;
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- module.exports = function(urlOrFunctions) {
4
- return async function(context, commands) {
3
+ module.exports = function (urlOrFunctions) {
4
+ return async function (context, commands) {
5
5
  for (let urlOrFunction of urlOrFunctions) {
6
6
  if (typeof urlOrFunction === 'function') {
7
7
  await urlOrFunction(context, commands);
@@ -70,8 +70,9 @@ class SeleniumRunner {
70
70
  this.driver = await timeout(
71
71
  builder.createWebDriver(this.baseDir, this.options),
72
72
  this.options.timeouts.browserStart,
73
- `Failed to start ${this.options.browser} in ${this.options.timeouts
74
- .browserStart / 1000} seconds.`
73
+ `Failed to start ${this.options.browser} in ${
74
+ this.options.timeouts.browserStart / 1000
75
+ } seconds.`
75
76
  );
76
77
  break;
77
78
  } catch (e) {
@@ -85,9 +86,9 @@ class SeleniumRunner {
85
86
  throw e;
86
87
  } else {
87
88
  log.info(
88
- `${this.options.browser} failed to start, trying ${tries -
89
- i -
90
- 1} more time(s): ${e.message}`
89
+ `${this.options.browser} failed to start, trying ${
90
+ tries - i - 1
91
+ } more time(s): ${e.message}`
91
92
  );
92
93
  }
93
94
  }
@@ -167,11 +168,13 @@ class SeleniumRunner {
167
168
  try {
168
169
  const pageCompleteCheckCondition = new Condition(
169
170
  'for page complete check script to return true',
170
- function(d) {
171
- return d.executeScript(pageCompleteCheck, waitTime).then(function(t) {
172
- log.verbose('PageCompleteCheck returned %s', t);
173
- return t === true;
174
- });
171
+ function (d) {
172
+ return d
173
+ .executeScript(pageCompleteCheck, waitTime)
174
+ .then(function (t) {
175
+ log.verbose('PageCompleteCheck returned %s', t);
176
+ return t === true;
177
+ });
175
178
  }
176
179
  );
177
180
  log.debug(
@@ -297,9 +300,9 @@ class SeleniumRunner {
297
300
  log.info(
298
301
  `URL ${url} failed to load, the ${
299
302
  this.options.browser
300
- } are still on ${startURI} , trying ${tries -
301
- i -
302
- 1} more time(s) but first wait for ${waitTime} ms.`
303
+ } are still on ${startURI} , trying ${
304
+ tries - i - 1
305
+ } more time(s) but first wait for ${waitTime} ms.`
303
306
  );
304
307
 
305
308
  if (i === tries - 1) {
@@ -476,13 +479,11 @@ class SeleniumRunner {
476
479
  */
477
480
  async getLogs(logType) {
478
481
  return timeout(
479
- this.driver
480
- .manage()
481
- .logs()
482
- .get(logType),
482
+ this.driver.manage().logs().get(logType),
483
483
  this.options.timeouts.logs,
484
- `Extracting logs from ${this.options.browser} took more than ${this
485
- .options.timeouts.logs / 1000} seconds.`
484
+ `Extracting logs from ${this.options.browser} took more than ${
485
+ this.options.timeouts.logs / 1000
486
+ } seconds.`
486
487
  );
487
488
  }
488
489
 
@@ -626,9 +627,9 @@ class SeleniumRunner {
626
627
  if (!script) {
627
628
  let func = category[scriptName].function;
628
629
  if (!func) {
629
- throw 'Function and script cannot both be null in ' +
630
- scriptName +
631
- '.';
630
+ throw (
631
+ 'Function and script cannot both be null in ' + scriptName + '.'
632
+ );
632
633
  }
633
634
  // We wrap the source code of the function in parenthesis
634
635
  // "(...)" to contain it in a separate scope. We add a
@@ -13,7 +13,7 @@ const safari = require('../../safari/webdriver/builder');
13
13
  * @returns {!Promise<webdriver.WebDriver>} a promise that resolves to the webdriver,
14
14
  * or rejects if the current configuration is invalid.
15
15
  */
16
- module.exports.createWebDriver = async function(baseDir, options) {
16
+ module.exports.createWebDriver = async function (baseDir, options) {
17
17
  const browser = options.browser || 'chrome';
18
18
  const seleniumUrl = options.selenium ? options.selenium.url : undefined;
19
19
  const capabilities = options.selenium
@@ -7,7 +7,7 @@ const isEmpty = require('lodash.isempty');
7
7
  const webdriver = require('selenium-webdriver');
8
8
  const setupChromiumOptions = require('../../chrome/webdriver/setupChromiumOptions');
9
9
 
10
- module.exports.configureBuilder = function(builder, baseDir, options) {
10
+ module.exports.configureBuilder = function (builder, baseDir, options) {
11
11
  const edgeConfig = options.edge || {};
12
12
  const chromeConfig = options.chrome || {};
13
13
 
@@ -46,7 +46,7 @@ function generateURL(port, testUrl, options) {
46
46
  });
47
47
  }
48
48
 
49
- module.exports = async function(url, browser, port, options) {
49
+ module.exports = async function (url, browser, port, options) {
50
50
  const configUrl = generateURL(port, url, options);
51
51
  log.debug('Configuring browser plugin via %s', configUrl);
52
52
  await browser.loadAndWait(configUrl);
@@ -40,9 +40,8 @@ class GeckoProfiler {
40
40
  const runner = this.runner;
41
41
  const firefoxConfig = this.firefoxConfig;
42
42
  const options = this.options;
43
- const chosenFeatures = firefoxConfig.geckoProfilerParams.features.split(
44
- ','
45
- );
43
+ const chosenFeatures =
44
+ firefoxConfig.geckoProfilerParams.features.split(',');
46
45
  const featureString = '["' + chosenFeatures.join('","') + '"]';
47
46
 
48
47
  const chosenThreads = firefoxConfig.geckoProfilerParams.threads.split(',');
@@ -4,7 +4,7 @@ const log = require('intel').getLogger('browsertime.firefox');
4
4
 
5
5
  // Get the HAR from Firefox
6
6
  // Using https://github.com/firefox-devtools/har-export-trigger
7
- module.exports = async function(runner, includeResponseBodies) {
7
+ module.exports = async function (runner, includeResponseBodies) {
8
8
  const script = `
9
9
  const callback = arguments[arguments.length - 1];
10
10
  async function triggerExport() {
@@ -13,7 +13,7 @@ const disableTrackingProtectionPreferences = require('../settings/disableTrackin
13
13
  const util = require('../../support/util');
14
14
  const { Android } = require('../../android');
15
15
 
16
- module.exports.configureBuilder = function(builder, baseDir, options) {
16
+ module.exports.configureBuilder = function (builder, baseDir, options) {
17
17
  // Here we configure everything that we need to start Firefox
18
18
  const firefoxConfig = options.firefox || {};
19
19
  const moduleRootPath = path.resolve(__dirname, '..', '..', '..');
@@ -83,18 +83,22 @@ module.exports.configureBuilder = function(builder, baseDir, options) {
83
83
  }
84
84
  }
85
85
 
86
- Object.keys(defaultFirefoxPreferences).forEach(function(pref) {
87
- ffOptions.setPreference(pref, defaultFirefoxPreferences[pref]);
88
- });
86
+ if (!firefoxConfig.noDefaultPrefs) {
87
+ Object.keys(defaultFirefoxPreferences).forEach(function (pref) {
88
+ ffOptions.setPreference(pref, defaultFirefoxPreferences[pref]);
89
+ });
90
+ } else {
91
+ log.info('Skip setting default preferences for Firefox');
92
+ }
89
93
 
90
94
  if (firefoxConfig.disableSafeBrowsing) {
91
- Object.keys(disableSafeBrowsingPreferences).forEach(function(pref) {
95
+ Object.keys(disableSafeBrowsingPreferences).forEach(function (pref) {
92
96
  ffOptions.setPreference(pref, disableSafeBrowsingPreferences[pref]);
93
97
  });
94
98
  }
95
99
 
96
100
  if (firefoxConfig.disableTrackingProtection) {
97
- Object.keys(disableTrackingProtectionPreferences).forEach(function(pref) {
101
+ Object.keys(disableTrackingProtectionPreferences).forEach(function (pref) {
98
102
  ffOptions.setPreference(pref, disableTrackingProtectionPreferences[pref]);
99
103
  });
100
104
  }
@@ -140,6 +144,7 @@ module.exports.configureBuilder = function(builder, baseDir, options) {
140
144
  ffOptions.setPreference('devtools.chrome.enabled', true);
141
145
 
142
146
  const userPrefs = util.toArray(firefoxConfig.preference);
147
+ log.debug('Set Firefox preference %j', userPrefs);
143
148
  for (const pref of userPrefs) {
144
149
  const name = pref.substr(0, pref.indexOf(':'));
145
150
  let value = pref.substr(pref.indexOf(':') + 1);
@@ -163,7 +168,7 @@ module.exports.configureBuilder = function(builder, baseDir, options) {
163
168
  get(firefoxConfig, 'developer') ? firefox.Channel.AURORA : undefined
164
169
  ];
165
170
 
166
- firefoxTypes = firefoxTypes.filter(function(n) {
171
+ firefoxTypes = firefoxTypes.filter(function (n) {
167
172
  return n !== undefined;
168
173
  });
169
174
 
@@ -206,13 +206,12 @@ class Firefox {
206
206
  ]) {
207
207
  // You can configure to not use content and perceptual.
208
208
  if (results[i].visualMetrics[progress]) {
209
- results[i].visualMetrics[
210
- progress
211
- ] = util.adjustVisualProgressTimestamps(
212
- results[i].visualMetrics[progress],
213
- geckoProfile.meta.startTime,
214
- firstFrameStartTime
215
- );
209
+ results[i].visualMetrics[progress] =
210
+ util.adjustVisualProgressTimestamps(
211
+ results[i].visualMetrics[progress],
212
+ geckoProfile.meta.startTime,
213
+ firstFrameStartTime
214
+ );
216
215
  }
217
216
  }
218
217
  geckoProfile.meta.visualMetrics = results[i].visualMetrics;
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
  const s = require('selenium-webdriver/safari');
3
3
 
4
- module.exports.configureBuilder = async function(builder, baseDir, options) {
4
+ module.exports.configureBuilder = async function (builder, baseDir, options) {
5
5
  const safariOptions = options.safari || {};
6
6
  builder
7
7
  .getCapabilities()
@@ -80,7 +80,7 @@ function generateScriptObject(name, path, contents) {
80
80
  content: null,
81
81
  isAsync:
82
82
  Object.getPrototypeOf(scriptAndMetadataObject.function) ===
83
- Object.getPrototypeOf(async function() {})
83
+ Object.getPrototypeOf(async function () {})
84
84
  };
85
85
  }
86
86
  } catch (error) {
@@ -282,6 +282,12 @@ module.exports.parseCommandLine = function parseCommandLine() {
282
282
  describe: 'Collect Chromes console log and save to disk.',
283
283
  group: 'chrome'
284
284
  })
285
+ .option('chrome.noDefaultOptions', {
286
+ type: 'boolean',
287
+ describe:
288
+ 'Prevent Browsertime from setting its default options for Chrome',
289
+ group: 'chrome'
290
+ })
285
291
  .option('cpu', {
286
292
  type: 'boolean',
287
293
  describe:
@@ -483,6 +489,12 @@ module.exports.parseCommandLine = function parseCommandLine() {
483
489
  type: 'boolean',
484
490
  group: 'firefox'
485
491
  })
492
+ .option('firefox.noDefaultPrefs', {
493
+ describe: 'Prevents browsertime from setting its default preferences.',
494
+ default: false,
495
+ type: 'boolean',
496
+ group: 'firefox'
497
+ })
486
498
  .option('firefox.disableSafeBrowsing', {
487
499
  describe: 'Disable safebrowsing.',
488
500
  default: true,
@@ -4,7 +4,7 @@ const path = require('path');
4
4
  const dayjs = require('dayjs');
5
5
  const util = require('../support/util');
6
6
  const log = require('intel').getLogger('browsertime');
7
- const AsyncFunction = Object.getPrototypeOf(async function() {}).constructor;
7
+ const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
8
8
 
9
9
  module.exports = {
10
10
  loadPrePostScripts(scripts) {
@@ -25,7 +25,7 @@ const sizeMap = {
25
25
  'iPad Pro': '1024x1366'
26
26
  };
27
27
 
28
- module.exports = function(options) {
28
+ module.exports = function (options) {
29
29
  // you cannot set the width/height for phone so just keep the viewport undefined
30
30
  if (isAndroidConfigured(options)) {
31
31
  return;
@@ -97,20 +97,19 @@ function addMetaToHAR(index, harPage, url, browserScript, options) {
97
97
  ? options.resultURL
98
98
  : options.resultURL + '/';
99
99
  if (options.screenshot) {
100
- _meta.screenshot = `${base}${pathToFolder(
101
- url,
102
- options
103
- )}screenshots/${index + 1}/afterPageCompleteCheck.${
104
- options.screenshotParams.type
105
- }`;
100
+ _meta.screenshot = `${base}${pathToFolder(url, options)}screenshots/${
101
+ index + 1
102
+ }/afterPageCompleteCheck.${options.screenshotParams.type}`;
106
103
  }
107
104
  if (options.video) {
108
- _meta.video = `${base}${pathToFolder(url, options)}video/${index +
109
- 1}.mp4`;
105
+ _meta.video = `${base}${pathToFolder(url, options)}video/${
106
+ index + 1
107
+ }.mp4`;
110
108
  }
111
109
  if (options.chrome && options.chrome.timeline) {
112
- _meta.timeline = `${base}${pathToFolder(url, options)}trace-${index +
113
- 1}.json.gz`;
110
+ _meta.timeline = `${base}${pathToFolder(url, options)}trace-${
111
+ index + 1
112
+ }.json.gz`;
114
113
  }
115
114
  }
116
115
  if (browserScript && browserScript.pageinfo) {
@@ -129,7 +128,7 @@ function jsonifyVisualProgress(visualProgress) {
129
128
  }
130
129
 
131
130
  module.exports = {
132
- addBrowser: function(har, name, version, comment) {
131
+ addBrowser: function (har, name, version, comment) {
133
132
  merge(har.log, {
134
133
  browser: {
135
134
  name,
@@ -145,7 +144,7 @@ module.exports = {
145
144
  return har;
146
145
  },
147
146
 
148
- addCreator: function(har, comment) {
147
+ addCreator: function (har, comment) {
149
148
  merge(har.log, {
150
149
  creator: {
151
150
  name: 'Browsertime',
@@ -161,7 +160,7 @@ module.exports = {
161
160
  return har;
162
161
  },
163
162
 
164
- getFullyLoaded: function(har) {
163
+ getFullyLoaded: function (har) {
165
164
  const fullyLoaded = [];
166
165
  const entries = Array.from(har.log.entries);
167
166
 
@@ -190,7 +189,7 @@ module.exports = {
190
189
  return fullyLoaded;
191
190
  },
192
191
 
193
- mergeHars: function(hars) {
192
+ mergeHars: function (hars) {
194
193
  if (isEmpty(hars)) {
195
194
  return undefined;
196
195
  }
@@ -10,7 +10,7 @@ function toSafeKey(key) {
10
10
  return key.replace(/[.~ /+|,:?&%–)(]|%7C/g, '-');
11
11
  }
12
12
 
13
- module.exports = function(url, options) {
13
+ module.exports = function (url, options) {
14
14
  if (options.useSameDir) {
15
15
  return '';
16
16
  } else {
@@ -31,19 +31,13 @@ module.exports = function(url, options) {
31
31
 
32
32
  if (useHash && !isEmpty(parsedUrl.hash)) {
33
33
  const md5 = crypto.createHash('md5'),
34
- hash = md5
35
- .update(parsedUrl.hash)
36
- .digest('hex')
37
- .substring(0, 8);
34
+ hash = md5.update(parsedUrl.hash).digest('hex').substring(0, 8);
38
35
  urlSegments.push('hash-' + hash);
39
36
  }
40
37
 
41
38
  if (!isEmpty(parsedUrl.search)) {
42
39
  const md5 = crypto.createHash('md5'),
43
- hash = md5
44
- .update(parsedUrl.search)
45
- .digest('hex')
46
- .substring(0, 8);
40
+ hash = md5.update(parsedUrl.search).digest('hex').substring(0, 8);
47
41
  urlSegments.push('query-' + hash);
48
42
  }
49
43
 
@@ -65,7 +59,7 @@ module.exports = function(url, options) {
65
59
 
66
60
  pathSegments.push('data');
67
61
 
68
- pathSegments.forEach(function(segment, index) {
62
+ pathSegments.forEach(function (segment, index) {
69
63
  if (segment) {
70
64
  pathSegments[index] = segment.replace(
71
65
  /[^-a-z0-9_.\u0621-\u064A]/gi,
@@ -3,7 +3,7 @@
3
3
  const log = require('intel').getLogger('browsertime');
4
4
  const delay = ms => new Promise(res => setTimeout(res, ms));
5
5
 
6
- module.exports = async function(browser, options) {
6
+ module.exports = async function (browser, options) {
7
7
  log.info('Accessing preURL %s', options.preURL);
8
8
  await browser.loadAndWait(options.preURL);
9
9
  await delay(options.preURLDelay ? options.preURLDelay : 1500);
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- module.exports = async function(startURL, driver, size) {
3
+ module.exports = async function (startURL, driver, size) {
4
4
  await driver.get(startURL);
5
5
  await driver.executeScript(
6
6
  `window.performance.setResourceTimingBufferSize(${size});`
@@ -137,7 +137,7 @@ class Statistics {
137
137
  stats.stddev() / Math.sqrt(stats.length).toFixed(decimals)
138
138
  ) // "standard deviation of the mean"
139
139
  };
140
- percentiles.forEach(function(p) {
140
+ percentiles.forEach(function (p) {
141
141
  let name = percentileName(p);
142
142
  node[name] = parseFloat(stats.percentile(p).toFixed(decimals));
143
143
  });
@@ -3,7 +3,7 @@
3
3
  const execa = require('execa');
4
4
  const log = require('intel').getLogger('browsertime');
5
5
 
6
- module.exports = async function(processName) {
6
+ module.exports = async function (processName) {
7
7
  const scriptArgs = ['-9', processName];
8
8
 
9
9
  log.debug('Kill all processes ' + processName);
@@ -17,9 +17,7 @@ const unlink = promisify(fs.unlink);
17
17
  const mkdir = promisify(fs.mkdir);
18
18
 
19
19
  const defaultDir = 'browsertime-results';
20
- let timestamp = dayjs()
21
- .format()
22
- .replace(/:/g, '');
20
+ let timestamp = dayjs().format().replace(/:/g, '');
23
21
 
24
22
  function pathNameFromUrl(url) {
25
23
  const parsedUrl = urlParser.parse(url),
@@ -29,10 +27,7 @@ function pathNameFromUrl(url) {
29
27
 
30
28
  if (!isEmpty(parsedUrl.search)) {
31
29
  const md5 = crypto.createHash('md5'),
32
- hash = md5
33
- .update(parsedUrl.search)
34
- .digest('hex')
35
- .substring(0, 8);
30
+ hash = md5.update(parsedUrl.search).digest('hex').substring(0, 8);
36
31
  pathSegments.push('query-' + hash);
37
32
  }
38
33
 
@@ -115,18 +110,18 @@ class StorageManager {
115
110
  }
116
111
 
117
112
  async gzip(inputFile, outputFile, removeInput) {
118
- const promise = new Promise(function(resolve, reject) {
113
+ const promise = new Promise(function (resolve, reject) {
119
114
  const gzip = zlib.createGzip();
120
115
  const input = fs.createReadStream(inputFile);
121
116
  const out = fs.createWriteStream(outputFile);
122
- out.on('finish', function() {
117
+ out.on('finish', function () {
123
118
  if (removeInput) {
124
119
  unlink(inputFile).then(() => resolve());
125
120
  } else {
126
121
  resolve();
127
122
  }
128
123
  });
129
- out.on('error', function(e) {
124
+ out.on('error', function (e) {
130
125
  log.error('Could not gzip %s to %s', inputFile, outputFile, e);
131
126
  reject();
132
127
  });
@@ -15,7 +15,7 @@ function isSmallish(options) {
15
15
  );
16
16
  }
17
17
 
18
- module.exports = async function(
18
+ module.exports = async function (
19
19
  inputFile,
20
20
  outputFile,
21
21
  videoMetrics,
@@ -3,7 +3,7 @@
3
3
  const execa = require('execa');
4
4
  const log = require('intel').getLogger('browsertime.video');
5
5
 
6
- module.exports = async function(src, dest, framerate) {
6
+ module.exports = async function (src, dest, framerate) {
7
7
  const scriptArgs = ['-nostdin', '-i', src, '-r', framerate, dest];
8
8
  log.info('Converting video to %s fps', framerate);
9
9
  return execa('ffmpeg', scriptArgs);
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const fs = require('fs');
4
- module.exports = function(options) {
4
+ module.exports = function (options) {
5
5
  // If the font is not part of the params and we're on macOS
6
6
  // we check that SFNSMono.ttf is available
7
7
  if (!options.videoParams.fontPath && process.platform === 'darwin') {