browsertime 16.17.0 → 17.0.0-beta.1

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 (121) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/bin/browsertime.js +43 -43
  3. package/bin/browsertimeWebPageReplay.js +10 -9
  4. package/browserscripts/pageinfo/generator.js +1 -1
  5. package/index.js +14 -13
  6. package/lib/android/gnirehtet.js +14 -15
  7. package/lib/android/index.js +92 -89
  8. package/lib/android/root.js +6 -9
  9. package/lib/chrome/chromeDevtoolsProtocol.js +46 -45
  10. package/lib/chrome/har.js +12 -13
  11. package/lib/chrome/longTaskMetrics.js +3 -5
  12. package/lib/chrome/parseCpuTrace.js +13 -10
  13. package/lib/chrome/settings/chromeAndroidOptions.js +1 -3
  14. package/lib/chrome/settings/chromeDesktopOptions.js +1 -3
  15. package/lib/chrome/settings/traceCategories.js +1 -3
  16. package/lib/chrome/traceCategoriesParser.js +35 -36
  17. package/lib/chrome/webdriver/builder.js +18 -26
  18. package/lib/chrome/webdriver/chromium.js +56 -46
  19. package/lib/chrome/webdriver/setupChromiumOptions.js +32 -27
  20. package/lib/connectivity/humble.js +13 -14
  21. package/lib/connectivity/index.js +74 -77
  22. package/lib/connectivity/trafficShapeParser.js +31 -35
  23. package/lib/core/engine/collector.js +22 -22
  24. package/lib/core/engine/command/addText.js +24 -27
  25. package/lib/core/engine/command/android.js +7 -11
  26. package/lib/core/engine/command/cache.js +3 -4
  27. package/lib/core/engine/command/chromeDevToolsProtocol.js +20 -20
  28. package/lib/core/engine/command/click.js +48 -49
  29. package/lib/core/engine/command/debug.js +3 -4
  30. package/lib/core/engine/command/javaScript.js +18 -19
  31. package/lib/core/engine/command/measure.js +31 -37
  32. package/lib/core/engine/command/meta.js +1 -4
  33. package/lib/core/engine/command/mouse/clickAndHold.js +36 -39
  34. package/lib/core/engine/command/mouse/contextClick.js +17 -18
  35. package/lib/core/engine/command/mouse/doubleClick.js +17 -19
  36. package/lib/core/engine/command/mouse/index.js +5 -9
  37. package/lib/core/engine/command/mouse/mouseMove.js +19 -23
  38. package/lib/core/engine/command/mouse/singleClick.js +15 -19
  39. package/lib/core/engine/command/navigation.js +12 -14
  40. package/lib/core/engine/command/screenshot.js +1 -4
  41. package/lib/core/engine/command/scroll.js +4 -7
  42. package/lib/core/engine/command/select.js +26 -26
  43. package/lib/core/engine/command/set.js +25 -23
  44. package/lib/core/engine/command/stopWatch.js +5 -8
  45. package/lib/core/engine/command/switch.js +18 -20
  46. package/lib/core/engine/command/util/lcpHighlightScript.js +1 -2
  47. package/lib/core/engine/command/util/lsHighlightScript.js +1 -2
  48. package/lib/core/engine/command/wait.js +18 -18
  49. package/lib/core/engine/index.js +82 -72
  50. package/lib/core/engine/iteration.js +83 -79
  51. package/lib/core/engine/run.js +5 -9
  52. package/lib/core/pageCompleteChecks/defaultPageCompleteCheck.js +1 -2
  53. package/lib/core/pageCompleteChecks/pageCompleteCheckByInactivity.js +1 -3
  54. package/lib/core/pageCompleteChecks/spaInactivity.js +1 -3
  55. package/lib/core/seleniumRunner.js +92 -100
  56. package/lib/core/webdriver/index.js +24 -21
  57. package/lib/edge/webdriver/builder.js +21 -26
  58. package/lib/extensionserver/httpServer.js +17 -21
  59. package/lib/extensionserver/index.js +8 -12
  60. package/lib/extensionserver/setup.js +12 -12
  61. package/lib/firefox/geckoProfiler.js +27 -21
  62. package/lib/firefox/getHAR.js +7 -8
  63. package/lib/firefox/memoryReport.js +9 -11
  64. package/lib/firefox/perfStats.js +5 -7
  65. package/lib/firefox/settings/disableSafeBrowsingPreferences.js +1 -3
  66. package/lib/firefox/settings/disableTrackingProtectionPreferences.js +1 -3
  67. package/lib/firefox/settings/firefoxPreferences.js +2 -4
  68. package/lib/firefox/settings/geckoProfilerDefaults.js +5 -9
  69. package/lib/firefox/webdriver/builder.js +66 -63
  70. package/lib/firefox/webdriver/firefox.js +44 -49
  71. package/lib/safari/webdriver/builder.js +4 -5
  72. package/lib/safari/webdriver/safari.js +4 -8
  73. package/lib/screenshot/defaults.js +1 -3
  74. package/lib/screenshot/index.js +24 -21
  75. package/lib/support/browserScript.js +65 -56
  76. package/lib/support/cli.js +120 -87
  77. package/lib/support/dns.js +6 -7
  78. package/lib/support/engineUtils.js +85 -38
  79. package/lib/support/errors.js +4 -13
  80. package/lib/support/fileUtil.js +81 -68
  81. package/lib/support/filters.js +15 -20
  82. package/lib/support/getViewPort.js +6 -7
  83. package/lib/support/har/index.js +208 -216
  84. package/lib/support/images/index.js +54 -26
  85. package/lib/support/logging.js +20 -17
  86. package/lib/support/pathToFolder.js +18 -23
  87. package/lib/support/preURL.js +5 -6
  88. package/lib/support/processes.js +4 -6
  89. package/lib/support/setResourceTimingBufferSize.js +2 -4
  90. package/lib/support/statistics.js +58 -56
  91. package/lib/support/stop.js +7 -8
  92. package/lib/support/storageManager.js +44 -44
  93. package/lib/support/tcpdump.js +22 -16
  94. package/lib/support/userTiming.js +7 -13
  95. package/lib/support/util.js +204 -224
  96. package/lib/support/xvfb.js +11 -13
  97. package/lib/video/defaults.js +6 -10
  98. package/lib/video/postprocessing/finetune/addTextToVideo.js +15 -15
  99. package/lib/video/postprocessing/finetune/convertFps.js +14 -8
  100. package/lib/video/postprocessing/finetune/getFont.js +7 -9
  101. package/lib/video/postprocessing/finetune/getTimingMetrics.js +19 -18
  102. package/lib/video/postprocessing/finetune/index.js +40 -36
  103. package/lib/video/postprocessing/finetune/removeOrange.js +10 -11
  104. package/lib/video/postprocessing/visualmetrics/extraMetrics.js +17 -13
  105. package/lib/video/postprocessing/visualmetrics/getVideoMetrics.js +12 -13
  106. package/lib/video/postprocessing/visualmetrics/visualMetrics.js +117 -128
  107. package/lib/video/screenRecording/android/recorder.js +12 -17
  108. package/lib/video/screenRecording/desktop/convert.js +13 -11
  109. package/lib/video/screenRecording/desktop/desktopRecorder.js +29 -24
  110. package/lib/video/screenRecording/desktop/ffmpegRecorder.js +60 -63
  111. package/lib/video/screenRecording/desktop/osx/getSPDisplaysDataType.js +4 -6
  112. package/lib/video/screenRecording/desktop/osx/getScreen.js +9 -10
  113. package/lib/video/screenRecording/firefox/firefoxWindowRecorder.js +54 -54
  114. package/lib/video/screenRecording/ios/convertToMp4.js +10 -11
  115. package/lib/video/screenRecording/ios/iosRecorder.js +23 -21
  116. package/lib/video/screenRecording/iosSimulator/convertToMp4.js +10 -11
  117. package/lib/video/screenRecording/iosSimulator/recorder.js +10 -9
  118. package/lib/video/screenRecording/recorder.js +8 -9
  119. package/lib/video/screenRecording/setOrangeBackground.js +5 -6
  120. package/lib/video/video.js +28 -34
  121. package/package.json +19 -17
@@ -1,21 +1,20 @@
1
- 'use strict';
1
+ import intel from 'intel';
2
+ import { computeMainThreadTasks } from '@sitespeed.io/tracium';
3
+ const log = intel.getLogger('browsertime.chrome.cpu');
2
4
 
3
- const log = require('intel').getLogger('browsertime.chrome.cpu');
4
- const Tracium = require('@sitespeed.io/tracium');
5
-
6
- function round(num, decimals = 3) {
5
+ function round(number_, decimals = 3) {
7
6
  const pow = Math.pow(10, decimals);
8
- return Math.round(num * pow) / pow;
7
+ return Math.round(number_ * pow) / pow;
9
8
  }
10
9
 
11
10
  function slowestFirst(a, b) {
12
11
  return b.value - a.value;
13
12
  }
14
13
 
15
- module.exports = async (tracelog, url) => {
14
+ export default async (tracelog, url) => {
16
15
  try {
17
16
  log.debug('Start parse Chrome trace log using Tracium.');
18
- const tasks = Tracium.computeMainThreadTasks(tracelog, {
17
+ const tasks = computeMainThreadTasks(tracelog, {
19
18
  flatten: true
20
19
  });
21
20
  log.debug('Finished parsing the trace log using Tracium.');
@@ -80,8 +79,12 @@ module.exports = async (tracelog, url) => {
80
79
 
81
80
  log.debug('Chrome trace log finished parsed and sorted.');
82
81
  return { categories, events, urls: cleanedUrls };
83
- } catch (e) {
84
- log.error('Could not parse the trace log from Chrome for url %s', url, e);
82
+ } catch (error) {
83
+ log.error(
84
+ 'Could not parse the trace log from Chrome for url %s',
85
+ url,
86
+ error
87
+ );
85
88
  return {};
86
89
  }
87
90
  };
@@ -1,11 +1,9 @@
1
- 'use strict';
2
-
3
1
  /**
4
2
  * Options when we run Chrome on Android
5
3
  * see https://github.com/GoogleChrome/chrome-launcher/blob/master/docs/chrome-flags-for-tools.md
6
4
  * https://peter.sh/experiments/chromium-command-line-switches/
7
5
  */
8
- module.exports = [
6
+ export default [
9
7
  '--disable-fre',
10
8
  // : Disable reporting to UMA, but allows for collection
11
9
  '--metrics-recording-only',
@@ -1,8 +1,6 @@
1
- 'use strict';
2
-
3
1
  // See https://github.com/GoogleChrome/chrome-launcher/blob/master/docs/chrome-flags-for-tools.md
4
2
  // https://peter.sh/experiments/chromium-command-line-switches/
5
- module.exports = [
3
+ export default [
6
4
  '--disable-background-networking',
7
5
  '--no-default-browser-check',
8
6
  '--no-first-run',
@@ -1,9 +1,7 @@
1
- 'use strict';
2
-
3
1
  /**
4
2
  * Default trace categories for the Chrome trace log.
5
3
  */
6
- module.exports = [
4
+ export default [
7
5
  '-*',
8
6
  'disabled-by-default-lighthouse',
9
7
  'v8',
@@ -1,6 +1,5 @@
1
- 'use strict';
2
-
3
- const log = require('intel').getLogger('browsertime.chrome.trace');
1
+ import intel from 'intel';
2
+ const log = intel.getLogger('browsertime.chrome.trace');
4
3
 
5
4
  // Adopting the Lighthouse way to clean the Trace log
6
5
  // https://github.com/GoogleChrome/lighthouse/blob/50a68ab2bf0115427e767e5e40dfe6be671902fe/lighthouse-core/config/config.js#L29-L110
@@ -15,20 +14,20 @@ function cleanTrace(trace, url) {
15
14
  const threads = [];
16
15
  const countsByThread = {};
17
16
  const traceStartEvents = [];
18
- const makeMockEvent = (evt, ts) => {
17
+ const makeMockEvent = (event, ts) => {
19
18
  return {
20
- pid: evt.pid,
21
- tid: evt.tid,
19
+ pid: event.pid,
20
+ tid: event.tid,
22
21
  ts: ts || 0, // default to 0 for now
23
22
  ph: 'I',
24
23
  cat: 'disabled-by-default-devtools.timeline',
25
24
  name: 'TracingStartedInPage',
26
25
  args: {
27
26
  data: {
28
- page: evt.frame,
27
+ page: event.frame,
29
28
  frames: [
30
29
  {
31
- frame: evt.frame,
30
+ frame: event.frame,
32
31
  name: '',
33
32
  url: url
34
33
  }
@@ -39,7 +38,8 @@ function cleanTrace(trace, url) {
39
38
  };
40
39
  };
41
40
 
42
- const makeNavStart = (evt, ts, tts, fid, url) => {
41
+ // eslint-disable-next-line unicorn/consistent-function-scoping
42
+ const makeNavStart = (event, ts, tts, fid, url) => {
43
43
  return {
44
44
  args: {
45
45
  data: {
@@ -52,8 +52,8 @@ function cleanTrace(trace, url) {
52
52
  cat: 'blink.user_timing',
53
53
  name: 'navigationStart',
54
54
  ph: 'R',
55
- pid: evt.pid,
56
- tid: evt.tid,
55
+ pid: event.pid,
56
+ tid: event.tid,
57
57
  ts: ts || 0,
58
58
  tts: tts || 0
59
59
  };
@@ -64,27 +64,29 @@ function cleanTrace(trace, url) {
64
64
  let name;
65
65
  let counter;
66
66
 
67
- traceEvents.forEach((evt, idx) => {
68
- if (evt.name.startsWith('TracingStartedIn')) {
69
- traceStartEvents.push(idx);
67
+ for (const [index_, event] of traceEvents.entries()) {
68
+ if (event.name.startsWith('TracingStartedIn')) {
69
+ traceStartEvents.push(index_);
70
70
  }
71
71
 
72
72
  // find the event's frame
73
73
  data =
74
- evt.args && (evt.args.data || evt.args.beginData || evt.args.counters);
75
- frame = (evt.args && evt.args.frame) || (data && (data.frame || data.page));
74
+ event.args &&
75
+ (event.args.data || event.args.beginData || event.args.counters);
76
+ frame =
77
+ (event.args && event.args.frame) || (data && (data.frame || data.page));
76
78
 
77
79
  if (!frame) {
78
- return;
80
+ continue;
79
81
  }
80
82
 
81
83
  // Increase occurences count of the frame
82
- name = `pid${evt.pid}-tid${evt.tid}-frame${frame}`;
84
+ name = `pid${event.pid}-tid${event.tid}-frame${frame}`;
83
85
  counter = countsByThread[name];
84
86
  if (!counter) {
85
87
  counter = {
86
- pid: evt.pid,
87
- tid: evt.tid,
88
+ pid: event.pid,
89
+ tid: event.tid,
88
90
  frame: frame,
89
91
  count: 0
90
92
  };
@@ -92,7 +94,7 @@ function cleanTrace(trace, url) {
92
94
  threads.push(counter);
93
95
  }
94
96
  counter.count++;
95
- });
97
+ }
96
98
 
97
99
  // find most active thread (and frame)
98
100
  threads.sort((a, b) => b.count - a.count);
@@ -107,10 +109,10 @@ function cleanTrace(trace, url) {
107
109
  traceEvents[traceStartEvents[0]] && traceEvents[traceStartEvents[0]].tts;
108
110
 
109
111
  // account for offset after removing items
110
- let i = 0;
112
+ let index = 0;
111
113
  for (let dup of traceStartEvents) {
112
- traceEvents.splice(dup - i, 1);
113
- i++;
114
+ traceEvents.splice(dup - index, 1);
115
+ index++;
114
116
  }
115
117
 
116
118
  // Add a new TracingStartedInPage event based on most active thread
@@ -151,15 +153,12 @@ function cleanTrace(trace, url) {
151
153
  return trace;
152
154
  }
153
155
 
154
- module.exports = {
155
- parse(events, url) {
156
- // const cleaned = [];
157
-
158
- /*for (let event of events) {
159
- if (event.method === 'Tracing.dataCollected') {
160
- cleaned.push(event.params);
161
- }
162
- }*/
163
- return cleanTrace({ traceEvents: events }, url);
164
- }
165
- };
156
+ export function parse(events, url) {
157
+ // const cleaned = [];
158
+ /*for (let event of events) {
159
+ if (event.method === 'Tracing.dataCollected') {
160
+ cleaned.push(event.params);
161
+ }
162
+ }*/
163
+ return cleanTrace({ traceEvents: events }, url);
164
+ }
@@ -1,28 +1,26 @@
1
- 'use strict';
2
-
3
- const chrome = require('selenium-webdriver/chrome');
4
- const webdriver = require('selenium-webdriver');
5
- const proxy = require('selenium-webdriver/proxy');
6
- const pick = require('lodash.pick');
7
- const isEmpty = require('lodash.isempty');
8
- const get = require('lodash.get');
9
- const setupChromiumOptions = require('./setupChromiumOptions');
1
+ import pick from 'lodash.pick';
2
+ import isEmpty from 'lodash.isempty';
3
+ import get from 'lodash.get';
4
+ import { logging } from 'selenium-webdriver';
5
+ import { ServiceBuilder, Options } from 'selenium-webdriver/chrome.js';
6
+ import { pac, manual } from 'selenium-webdriver/proxy.js';
7
+ import setupChromiumOptions from './setupChromiumOptions.js';
10
8
 
11
9
  /**
12
10
  * Configure a WebDriver builder based on the specified options.
13
11
  * @param builder
14
12
  * @param {Object} options the options for a web driver.
15
13
  */
16
- module.exports.configureBuilder = function (builder, baseDir, options) {
14
+ export async function configureBuilder(builder, baseDir, options) {
17
15
  const chromeConfig = options.chrome || {};
18
16
 
19
17
  let chromedriverPath = get(chromeConfig, 'chromedriverPath');
20
18
  if (!chromedriverPath) {
21
- const chromedriver = require('@sitespeed.io/chromedriver');
22
- chromedriverPath = chromedriver.binPath();
19
+ let chromedriver = await import('@sitespeed.io/chromedriver');
20
+ chromedriverPath = chromedriver.default.binPath();
23
21
  }
24
22
 
25
- const serviceBuilder = new chrome.ServiceBuilder(chromedriverPath);
23
+ const serviceBuilder = new ServiceBuilder(chromedriverPath);
26
24
 
27
25
  // Remove the check that matches the Chromedriver version with Chrome version.
28
26
  serviceBuilder.addArguments('--disable-build-check');
@@ -44,27 +42,21 @@ module.exports.configureBuilder = function (builder, baseDir, options) {
44
42
  const proxyPacSettings = pick(options.proxy, ['pac']);
45
43
 
46
44
  if (!isEmpty(proxyPacSettings)) {
47
- builder.setProxy(proxy.pac(proxyPacSettings));
45
+ builder.setProxy(pac(proxyPacSettings));
48
46
  }
49
47
 
50
48
  const proxySettings = pick(options.proxy, ['ftp', 'http', 'https', 'bypass']);
51
49
 
52
50
  if (!isEmpty(proxySettings)) {
53
- builder.setProxy(proxy.manual(proxySettings));
51
+ builder.setProxy(manual(proxySettings));
54
52
  }
55
53
 
56
- let chromeOptions = new chrome.Options();
57
- let logPrefs = new webdriver.logging.Preferences();
58
- logPrefs.setLevel(
59
- webdriver.logging.Type.PERFORMANCE,
60
- webdriver.logging.Level.ALL
61
- );
54
+ let chromeOptions = new Options();
55
+ let logPrefs = new logging.Preferences();
56
+ logPrefs.setLevel(logging.Type.PERFORMANCE, logging.Level.ALL);
62
57
 
63
58
  if (chromeConfig.collectConsoleLog) {
64
- logPrefs.setLevel(
65
- webdriver.logging.Type.BROWSER,
66
- webdriver.logging.Level.ALL
67
- );
59
+ logPrefs.setLevel(logging.Type.BROWSER, logging.Level.ALL);
68
60
  }
69
61
 
70
62
  chromeOptions.setLoggingPrefs(logPrefs);
@@ -77,4 +69,4 @@ module.exports.configureBuilder = function (builder, baseDir, options) {
77
69
  setupChromiumOptions(chromeOptions, chromeConfig, options, baseDir);
78
70
 
79
71
  builder.setChromeOptions(chromeOptions);
80
- };
72
+ }
@@ -1,22 +1,22 @@
1
- 'use strict';
2
-
3
- const log = require('intel').getLogger('browsertime.chrome');
4
- const { promisify } = require('util');
5
- const { Type } = require('selenium-webdriver').logging;
6
- const cpuMetrics = require('../longTaskMetrics');
7
- const fs = require('fs');
8
- const path = require('path');
9
- const parseCpuTrace = require('../parseCpuTrace');
10
- const har = require('../har');
11
- const harBuilder = require('../../support/har');
12
- const util = require('../../support/util');
13
- const webdriver = require('selenium-webdriver');
14
- const traceCategoriesParser = require('../traceCategoriesParser');
15
- const pathToFolder = require('../../support/pathToFolder');
16
- const ChromeDevtoolsProtocol = require('../chromeDevtoolsProtocol');
17
- const { Android } = require('../../android');
18
- const unlink = promisify(fs.unlink);
19
- const rm = promisify(fs.rm);
1
+ import { promisify } from 'node:util';
2
+ import { unlink as _unlink, rm as _rm } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { logging } from 'selenium-webdriver';
5
+ import intel from 'intel';
6
+ const log = intel.getLogger('browsertime.chrome');
7
+ const { Type } = logging;
8
+ import cpuMetrics from '../longTaskMetrics.js';
9
+ import parseCpuTrace from '../parseCpuTrace.js';
10
+ import har from '../har.js';
11
+ import { getEmptyHAR, mergeHars } from '../../support/har/index.js';
12
+ import { toArray } from '../../support/util.js';
13
+ import { logging as _logging } from 'selenium-webdriver';
14
+ import { parse } from '../traceCategoriesParser.js';
15
+ import pathToFolder from '../../support/pathToFolder.js';
16
+ import ChromeDevtoolsProtocol from '../chromeDevtoolsProtocol.js';
17
+ import { Android, isAndroidConfigured } from '../../android/index.js';
18
+ const unlink = promisify(_unlink);
19
+ const rm = promisify(_rm);
20
20
 
21
21
  class Chromium {
22
22
  constructor(storageManager, options) {
@@ -41,7 +41,7 @@ class Chromium {
41
41
  */
42
42
  async beforeBrowserStart() {
43
43
  this.events = [];
44
- if (this.options.android) {
44
+ if (isAndroidConfigured(this.options)) {
45
45
  this.android = new Android(this.options);
46
46
  if (this.options.androidPower) {
47
47
  await this.android.startPowerTesting();
@@ -64,7 +64,7 @@ class Chromium {
64
64
  // We create the cdp as early as possible so it can be used in scripts
65
65
  // https://bugs.chromium.org/p/chromium/issues/detail?id=824626
66
66
  // https://github.com/cyrus-and/chrome-remote-interface/issues/332
67
- if (this.options.android) {
67
+ if (isAndroidConfigured(this.options)) {
68
68
  await this.android.addDevtoolsFw();
69
69
  }
70
70
 
@@ -224,12 +224,12 @@ class Chromium {
224
224
 
225
225
  if (this.chrome.collectNetLog && !this.chrome.android) {
226
226
  await this.storageManager.createSubDataDir(
227
- path.join(pathToFolder(result.url, this.options))
227
+ join(pathToFolder(result.url, this.options))
228
228
  );
229
229
 
230
230
  await this.storageManager.gzip(
231
231
  `${this.baseDir}/chromeNetlog.json`,
232
- path.join(
232
+ join(
233
233
  this.baseDir,
234
234
  pathToFolder(result.url, this.options),
235
235
  `chromeNetlog-${index}.json.gz`
@@ -242,7 +242,7 @@ class Chromium {
242
242
  result.extraJson = {};
243
243
  }
244
244
  result.extraJson[`console-${index}.json`] = await runner.getLogs(
245
- webdriver.logging.Type.BROWSER
245
+ _logging.Type.BROWSER
246
246
  );
247
247
  }
248
248
 
@@ -268,17 +268,29 @@ class Chromium {
268
268
  const cleanedMetrics = {};
269
269
  let ns, fmp;
270
270
  for (let m of rawCDPMetrics.metrics) {
271
- if (m.name === 'DomContentLoaded' || m.name === 'Timestamp') {
272
- // skip
273
- } else if (m.name === 'FirstMeaningfulPaint') {
274
- fmp = m.value;
275
- } else if (m.name === 'NavigationStart') {
276
- ns = m.value;
277
- } else {
278
- if (m.name.indexOf('Duration') > -1) {
279
- cleanedMetrics[m.name] = m.value * 1000;
280
- } else {
281
- cleanedMetrics[m.name] = m.value;
271
+ switch (m.name) {
272
+ case 'DomContentLoaded':
273
+ case 'Timestamp': {
274
+ // skip
275
+
276
+ break;
277
+ }
278
+ case 'FirstMeaningfulPaint': {
279
+ fmp = m.value;
280
+
281
+ break;
282
+ }
283
+ case 'NavigationStart': {
284
+ ns = m.value;
285
+
286
+ break;
287
+ }
288
+ default: {
289
+ if (m.name.includes('Duration')) {
290
+ cleanedMetrics[m.name] = m.value * 1000;
291
+ } else {
292
+ cleanedMetrics[m.name] = m.value;
293
+ }
282
294
  }
283
295
  }
284
296
  }
@@ -303,13 +315,13 @@ class Chromium {
303
315
 
304
316
  if (this.chrome.collectNetLog && this.chrome.android) {
305
317
  // THIS needs to be unique per page
306
- const filename = path.join(
318
+ const filename = join(
307
319
  this.baseDir,
308
320
  pathToFolder(result.url, this.options),
309
321
  `chromeNetlog-${index}.json`
310
322
  );
311
323
 
312
- const gzFilename = path.join(
324
+ const gzFilename = join(
313
325
  this.baseDir,
314
326
  pathToFolder(result.url, this.options),
315
327
  `chromeNetlog-${index}.json.gz`
@@ -320,7 +332,7 @@ class Chromium {
320
332
  }
321
333
 
322
334
  if (this.collectTracingEvents) {
323
- const trace = traceCategoriesParser.parse(this.events, result.url);
335
+ const trace = parse(this.events, result.url);
324
336
  result.extraJson[`trace-${index}.json`] = trace;
325
337
  const cpu = await parseCpuTrace(trace, result.url);
326
338
  result.cpu = cpu;
@@ -433,7 +445,7 @@ class Chromium {
433
445
  if (this.skipHar) {
434
446
  return;
435
447
  }
436
- this.hars.push(harBuilder.getEmptyHAR(url, this.options.browser));
448
+ this.hars.push(getEmptyHAR(url, this.options.browser));
437
449
  }
438
450
 
439
451
  /**
@@ -464,15 +476,15 @@ class Chromium {
464
476
  this.chrome.cleanUserDataDir &&
465
477
  !this.chrome.android
466
478
  ) {
467
- const args = util.toArray(this.chrome.args);
479
+ const args = toArray(this.chrome.args);
468
480
  for (let arg of args) {
469
481
  if (arg.includes('user-data-dir')) {
470
482
  const userDataDir = arg.split('=')[1];
471
483
  try {
472
484
  await rm(userDataDir, { recursive: true });
473
485
  log.info(`Deleted user data dir: ${userDataDir}`);
474
- } catch (e) {
475
- log.error(`Could not delete user data dir: ${userDataDir}`, e);
486
+ } catch (error) {
487
+ log.error(`Could not delete user data dir: ${userDataDir}`, error);
476
488
  }
477
489
  }
478
490
  }
@@ -480,9 +492,7 @@ class Chromium {
480
492
  }
481
493
 
482
494
  async getHARs() {
483
- if (!this.skipHar) {
484
- return { har: harBuilder.mergeHars(this.hars) };
485
- } else return {};
495
+ return !this.skipHar ? { har: mergeHars(this.hars) } : {};
486
496
  }
487
497
 
488
498
  async setCookies(url, cookies) {
@@ -490,4 +500,4 @@ class Chromium {
490
500
  }
491
501
  }
492
502
 
493
- module.exports = Chromium;
503
+ export default Chromium;
@@ -1,9 +1,11 @@
1
- const fs = require('fs');
2
- const defaultChromeOptions = require('../settings/chromeDesktopOptions');
3
- const defaultAndroidChromeOptions = require('../settings/chromeAndroidOptions');
4
- const getViewPort = require('../../support/getViewPort');
5
- const util = require('../../support/util');
6
- const log = require('intel').getLogger('browsertime.chrome');
1
+ import { readFileSync } from 'node:fs';
2
+ import intel from 'intel';
3
+ import defaultChromeOptions from '../settings/chromeDesktopOptions.js';
4
+ import defaultAndroidChromeOptions from '../settings/chromeAndroidOptions.js';
5
+ import getViewPort from '../../support/getViewPort.js';
6
+ import { toArray } from '../../support/util.js';
7
+ import { isAndroidConfigured } from '../../android/index.js';
8
+ const log = intel.getLogger('browsertime.chrome');
7
9
 
8
10
  const CHROME_AMD_EDGE_INTERNAL_PHONE_HOME = [
9
11
  '"MAP cache.pack.google.com 127.0.0.1"',
@@ -16,9 +18,10 @@ const CHROME_AMD_EDGE_INTERNAL_PHONE_HOME = [
16
18
  '"MAP optimizationguide-pa.googleapis.com 127.0.0.1"'
17
19
  ];
18
20
 
19
- module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
21
+ export default function (seleniumOptions, browserOptions, options, baseDir) {
20
22
  // Fixing save password popup, only on Desktop
21
- if (!options.android) {
23
+
24
+ if (!isAndroidConfigured(options)) {
22
25
  seleniumOptions.setUserPreferences({
23
26
  'profile.password_manager_enable': false,
24
27
  'profile.default_content_setting_values.notifications': 2,
@@ -53,7 +56,7 @@ module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
53
56
  browserOptions.webPageReplayHostResolver &&
54
57
  browserOptions.webPageReplayRecord
55
58
  ) {
56
- const firstPartyDomains = util.toArray(browserOptions.blockDomainsExcept);
59
+ const firstPartyDomains = toArray(browserOptions.blockDomainsExcept);
57
60
  let excludes = '';
58
61
  for (let domain of firstPartyDomains) {
59
62
  excludes += ` MAP ${domain}:80 127.0.0.1:${browserOptions.webPageReplayHTTPPort},`;
@@ -70,18 +73,18 @@ module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
70
73
  } // If we do not use WebPageReplay but wanna block on domain
71
74
  else if (browserOptions.blockDomainsExcept) {
72
75
  let excludes = '';
73
- let excludesDomains = util.toArray(browserOptions.blockDomainsExcept);
76
+ let excludesDomains = toArray(browserOptions.blockDomainsExcept);
74
77
  for (let domain of excludesDomains) {
75
78
  excludes += 'MAP * 127.0.0.1, EXCLUDE ' + domain + ',';
76
79
  }
77
80
  seleniumOptions.addArguments('--host-resolver-rules=' + excludes);
78
81
  } else {
79
82
  // Make sure we only set this if we do not have any other host resolver rules
80
- const chromeCommandLineArgs = util.toArray(browserOptions.args);
81
- const argsWithHostResolverRules = chromeCommandLineArgs.filter(arg =>
82
- arg.includes('host-resolver-rules')
83
+ const chromeCommandLineArguments = toArray(browserOptions.args);
84
+ const argumentsWithHostResolverRules = chromeCommandLineArguments.filter(
85
+ argument => argument.includes('host-resolver-rules')
83
86
  );
84
- if (argsWithHostResolverRules.length === 0) {
87
+ if (argumentsWithHostResolverRules.length === 0) {
85
88
  seleniumOptions.addArguments(
86
89
  '--host-resolver-rules=' + CHROME_AMD_EDGE_INTERNAL_PHONE_HOME.join(',')
87
90
  );
@@ -94,7 +97,7 @@ module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
94
97
  : options.extension;
95
98
  for (const extension of extensions) {
96
99
  seleniumOptions.addExtensions(
97
- fs.readFileSync(extension, { encoding: 'base64' })
100
+ readFileSync(extension, { encoding: 'base64' })
98
101
  );
99
102
  }
100
103
  }
@@ -103,8 +106,8 @@ module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
103
106
  seleniumOptions.addArguments('--auto-open-devtools-for-tabs');
104
107
  }
105
108
 
106
- const perfLogConf = { enableNetwork: true, enablePage: true };
107
- seleniumOptions.setPerfLoggingPrefs(perfLogConf);
109
+ const perfLogConfig = { enableNetwork: true, enablePage: true };
110
+ seleniumOptions.setPerfLoggingPrefs(perfLogConfig);
108
111
 
109
112
  if (options.userAgent) {
110
113
  seleniumOptions.addArguments('--user-agent=' + options.userAgent);
@@ -115,7 +118,9 @@ module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
115
118
  }
116
119
 
117
120
  if (browserOptions.collectNetLog) {
118
- const dir = !browserOptions.android ? baseDir : '/data/local/tmp';
121
+ const dir = !isAndroidConfigured(browserOptions)
122
+ ? baseDir
123
+ : '/data/local/tmp';
119
124
  seleniumOptions.addArguments(`--log-net-log=${dir}/chromeNetlog.json`);
120
125
  const level = browserOptions.netLogCaptureMode || 'IncludeSensitive';
121
126
  seleniumOptions.addArguments(`--net-log-capture-mode=${level}`);
@@ -141,17 +146,17 @@ module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
141
146
  // for new profiles
142
147
  // disable it with ChromeWhatsNewUI
143
148
  if (browserOptions.args) {
144
- const chromeCommandLineArgs = util.toArray(browserOptions.args);
145
- for (const arg of chromeCommandLineArgs) {
149
+ const chromeCommandLineArguments = toArray(browserOptions.args);
150
+ for (const argument of chromeCommandLineArguments) {
146
151
  if (
147
- arg.indexOf('disable-features') > -1 &&
148
- arg.indexOf('ChromeWhatsNewUI') === -1
152
+ argument.includes('disable-features') &&
153
+ !argument.includes('ChromeWhatsNewUI')
149
154
  ) {
150
- seleniumOptions.addArguments(`${arg},ChromeWhatsNewUI`);
151
- log.debug('Set Chrome args %j', `${arg},ChromeWhatsNewUI`);
155
+ seleniumOptions.addArguments(`${argument},ChromeWhatsNewUI`);
156
+ log.debug('Set Chrome args %j', `${argument},ChromeWhatsNewUI`);
152
157
  } else {
153
- seleniumOptions.addArguments(arg);
154
- log.debug('Set Chrome args %j', arg);
158
+ seleniumOptions.addArguments(argument);
159
+ log.debug('Set Chrome args %j', argument);
155
160
  }
156
161
  }
157
162
  } else {
@@ -188,4 +193,4 @@ module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
188
193
 
189
194
  log.debug('Setting the following Selenium options: %j', seleniumOptions);
190
195
  return seleniumOptions;
191
- };
196
+ }