browsertime 17.0.0-beta.4 → 17.1.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 (99) hide show
  1. package/CHANGELOG.md +30 -13
  2. package/bin/browsertime.js +4 -4
  3. package/bin/browsertimeWebPageReplay.js +2 -2
  4. package/browsertime/visualmetrics-portable.py +54 -50
  5. package/index.js +2 -2
  6. package/lib/android/gnirehtet.js +1 -2
  7. package/lib/android/root.js +57 -16
  8. package/lib/chrome/chromeDevtoolsProtocol.js +6 -3
  9. package/lib/chrome/har.js +1 -1
  10. package/lib/chrome/longTaskMetrics.js +1 -1
  11. package/lib/chrome/parseCpuTrace.js +2 -2
  12. package/lib/chrome/settings/chromeAndroidOptions.js +1 -1
  13. package/lib/chrome/settings/chromeDesktopOptions.js +1 -1
  14. package/lib/chrome/settings/traceCategories.js +1 -1
  15. package/lib/chrome/traceCategoriesParser.js +3 -3
  16. package/lib/chrome/webdriver/builder.js +1 -1
  17. package/lib/chrome/webdriver/chromium.js +13 -17
  18. package/lib/chrome/webdriver/setupChromiumOptions.js +18 -13
  19. package/lib/connectivity/humble.js +10 -12
  20. package/lib/connectivity/index.js +1 -1
  21. package/lib/core/engine/collector.js +2 -4
  22. package/lib/core/engine/command/addText.js +1 -2
  23. package/lib/core/engine/command/android.js +1 -1
  24. package/lib/core/engine/command/cache.js +1 -2
  25. package/lib/core/engine/command/chromeDevToolsProtocol.js +9 -2
  26. package/lib/core/engine/command/click.js +1 -2
  27. package/lib/core/engine/command/debug.js +1 -3
  28. package/lib/core/engine/command/javaScript.js +1 -2
  29. package/lib/core/engine/command/measure.js +13 -15
  30. package/lib/core/engine/command/meta.js +1 -1
  31. package/lib/core/engine/command/navigation.js +1 -1
  32. package/lib/core/engine/command/screenshot.js +1 -1
  33. package/lib/core/engine/command/scroll.js +1 -1
  34. package/lib/core/engine/command/select.js +1 -1
  35. package/lib/core/engine/command/set.js +1 -1
  36. package/lib/core/engine/command/stopWatch.js +1 -1
  37. package/lib/core/engine/command/switch.js +44 -1
  38. package/lib/core/engine/command/util/lcpHighlightScript.js +1 -1
  39. package/lib/core/engine/command/util/lsHighlightScript.js +1 -1
  40. package/lib/core/engine/command/wait.js +1 -1
  41. package/lib/core/engine/index.js +12 -12
  42. package/lib/core/engine/iteration.js +27 -27
  43. package/lib/core/engine/run.js +1 -1
  44. package/lib/core/pageCompleteChecks/defaultPageCompleteCheck.js +1 -1
  45. package/lib/core/pageCompleteChecks/pageCompleteCheckByInactivity.js +1 -1
  46. package/lib/core/pageCompleteChecks/spaInactivity.js +1 -1
  47. package/lib/core/seleniumRunner.js +9 -11
  48. package/lib/edge/webdriver/builder.js +1 -1
  49. package/lib/extensionserver/index.js +2 -4
  50. package/lib/extensionserver/setup.js +1 -1
  51. package/lib/firefox/geckoProfiler.js +46 -16
  52. package/lib/firefox/getHAR.js +1 -1
  53. package/lib/firefox/memoryReport.js +1 -1
  54. package/lib/firefox/settings/disableSafeBrowsingPreferences.js +1 -1
  55. package/lib/firefox/settings/disableTrackingProtectionPreferences.js +1 -1
  56. package/lib/firefox/settings/firefoxPreferences.js +1 -1
  57. package/lib/firefox/webdriver/builder.js +9 -9
  58. package/lib/firefox/webdriver/firefox.js +24 -6
  59. package/lib/safari/webdriver/safari.js +1 -1
  60. package/lib/screenshot/defaults.js +1 -1
  61. package/lib/screenshot/index.js +3 -5
  62. package/lib/support/cli.js +5 -5
  63. package/lib/support/dns.js +6 -1
  64. package/lib/support/engineUtils.js +5 -13
  65. package/lib/support/getViewPort.js +1 -1
  66. package/lib/support/har/index.js +6 -8
  67. package/lib/support/images/index.js +1 -1
  68. package/lib/support/logging.js +1 -1
  69. package/lib/support/pathToFolder.js +4 -4
  70. package/lib/support/preURL.js +1 -1
  71. package/lib/support/processes.js +1 -1
  72. package/lib/support/setResourceTimingBufferSize.js +1 -1
  73. package/lib/support/stop.js +1 -1
  74. package/lib/support/storageManager.js +1 -3
  75. package/lib/support/tcpdump.js +2 -2
  76. package/lib/support/xvfb.js +2 -4
  77. package/lib/video/postprocessing/finetune/addTextToVideo.js +3 -3
  78. package/lib/video/postprocessing/finetune/convertFps.js +1 -1
  79. package/lib/video/postprocessing/finetune/getFont.js +1 -1
  80. package/lib/video/postprocessing/finetune/getTimingMetrics.js +2 -2
  81. package/lib/video/postprocessing/finetune/index.js +4 -4
  82. package/lib/video/postprocessing/finetune/removeOrange.js +1 -1
  83. package/lib/video/postprocessing/visualmetrics/extraMetrics.js +1 -1
  84. package/lib/video/postprocessing/visualmetrics/getVideoMetrics.js +2 -2
  85. package/lib/video/screenRecording/android/recorder.js +1 -1
  86. package/lib/video/screenRecording/desktop/convert.js +1 -1
  87. package/lib/video/screenRecording/desktop/desktopRecorder.js +3 -3
  88. package/lib/video/screenRecording/desktop/ffmpegRecorder.js +6 -6
  89. package/lib/video/screenRecording/desktop/osx/getSPDisplaysDataType.js +1 -1
  90. package/lib/video/screenRecording/desktop/osx/getScreen.js +1 -1
  91. package/lib/video/screenRecording/firefox/firefoxWindowRecorder.js +1 -1
  92. package/lib/video/screenRecording/ios/convertToMp4.js +1 -1
  93. package/lib/video/screenRecording/ios/iosRecorder.js +2 -2
  94. package/lib/video/screenRecording/iosSimulator/convertToMp4.js +1 -1
  95. package/lib/video/screenRecording/iosSimulator/recorder.js +2 -2
  96. package/lib/video/screenRecording/recorder.js +6 -6
  97. package/lib/video/screenRecording/setOrangeBackground.js +1 -1
  98. package/lib/video/video.js +9 -11
  99. package/package.json +18 -18
@@ -5,20 +5,20 @@ import { logging } from 'selenium-webdriver';
5
5
  import intel from 'intel';
6
6
  const log = intel.getLogger('browsertime.chrome');
7
7
  const { Type } = logging;
8
- import cpuMetrics from '../longTaskMetrics.js';
9
- import parseCpuTrace from '../parseCpuTrace.js';
10
- import har from '../har.js';
8
+ import { longTaskMetrics } from '../longTaskMetrics.js';
9
+ import { parseCPUTrace } from '../parseCpuTrace.js';
10
+ import { getHar } from '../har.js';
11
11
  import { getEmptyHAR, mergeHars } from '../../support/har/index.js';
12
12
  import { toArray } from '../../support/util.js';
13
13
  import { logging as _logging } from 'selenium-webdriver';
14
14
  import { parse } from '../traceCategoriesParser.js';
15
- import pathToFolder from '../../support/pathToFolder.js';
16
- import ChromeDevtoolsProtocol from '../chromeDevtoolsProtocol.js';
15
+ import { pathToFolder } from '../../support/pathToFolder.js';
16
+ import { ChromeDevtoolsProtocol } from '../chromeDevtoolsProtocol.js';
17
17
  import { Android, isAndroidConfigured } from '../../android/index.js';
18
18
  const unlink = promisify(_unlink);
19
19
  const rm = promisify(_rm);
20
20
 
21
- class Chromium {
21
+ export class Chromium {
22
22
  constructor(storageManager, options) {
23
23
  this.options = options;
24
24
  this.chrome = options.chrome || {};
@@ -248,7 +248,7 @@ class Chromium {
248
248
 
249
249
  if (!this.skipHar) {
250
250
  this.hars.push(
251
- await har(
251
+ await getHar(
252
252
  runner,
253
253
  result,
254
254
  index,
@@ -286,11 +286,9 @@ class Chromium {
286
286
  break;
287
287
  }
288
288
  default: {
289
- if (m.name.includes('Duration')) {
290
- cleanedMetrics[m.name] = m.value * 1000;
291
- } else {
292
- cleanedMetrics[m.name] = m.value;
293
- }
289
+ cleanedMetrics[m.name] = m.name.includes('Duration')
290
+ ? m.value * 1000
291
+ : m.value;
294
292
  }
295
293
  }
296
294
  }
@@ -334,7 +332,7 @@ class Chromium {
334
332
  if (this.collectTracingEvents) {
335
333
  const trace = parse(this.events, result.url);
336
334
  result.extraJson[`trace-${index}.json`] = trace;
337
- const cpu = await parseCpuTrace(trace, result.url);
335
+ const cpu = await parseCPUTrace(trace, result.url);
338
336
  result.cpu = cpu;
339
337
 
340
338
  // Collect render blocking info
@@ -420,7 +418,7 @@ class Chromium {
420
418
  result.browserScripts.pageinfo &&
421
419
  result.browserScripts.pageinfo.longTask
422
420
  ) {
423
- const cpuData = cpuMetrics(result, this.options);
421
+ const cpuData = longTaskMetrics(result, this.options);
424
422
  if (result.cpu) {
425
423
  result.cpu.longTasks = cpuData.longTasks;
426
424
  } else {
@@ -492,12 +490,10 @@ class Chromium {
492
490
  }
493
491
 
494
492
  async getHARs() {
495
- return !this.skipHar ? { har: mergeHars(this.hars) } : {};
493
+ return this.skipHar ? {} : { har: mergeHars(this.hars) };
496
494
  }
497
495
 
498
496
  async setCookies(url, cookies) {
499
497
  return this.cdpClient.setCookies(url, cookies);
500
498
  }
501
499
  }
502
-
503
- export default Chromium;
@@ -1,8 +1,8 @@
1
1
  import { readFileSync } from 'node:fs';
2
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';
3
+ import { chromeDesktopOptions as defaultChromeOptions } from '../settings/chromeDesktopOptions.js';
4
+ import { chromeAndroidOptions as defaultAndroidChromeOptions } from '../settings/chromeAndroidOptions.js';
5
+ import { getViewPort } from '../../support/getViewPort.js';
6
6
  import { toArray } from '../../support/util.js';
7
7
  import { isAndroidConfigured } from '../../android/index.js';
8
8
  const log = intel.getLogger('browsertime.chrome');
@@ -19,7 +19,12 @@ const CHROME_AMD_EDGE_INTERNAL_PHONE_HOME = [
19
19
  '"MAP optimizationguide-pa.googleapis.com 127.0.0.1"'
20
20
  ];
21
21
 
22
- export default function (seleniumOptions, browserOptions, options, baseDir) {
22
+ export function setupChromiumOptions(
23
+ seleniumOptions,
24
+ browserOptions,
25
+ options,
26
+ baseDir
27
+ ) {
23
28
  // Fixing save password popup, only on Desktop
24
29
 
25
30
  if (!isAndroidConfigured(options)) {
@@ -93,9 +98,9 @@ export default function (seleniumOptions, browserOptions, options, baseDir) {
93
98
  }
94
99
 
95
100
  if (options.extension) {
96
- const extensions = !Array.isArray(options.extension)
97
- ? [options.extension]
98
- : options.extension;
101
+ const extensions = Array.isArray(options.extension)
102
+ ? options.extension
103
+ : [options.extension];
99
104
  for (const extension of extensions) {
100
105
  seleniumOptions.addExtensions(
101
106
  readFileSync(extension, { encoding: 'base64' })
@@ -119,9 +124,9 @@ export default function (seleniumOptions, browserOptions, options, baseDir) {
119
124
  }
120
125
 
121
126
  if (browserOptions.collectNetLog) {
122
- const dir = !isAndroidConfigured(browserOptions)
123
- ? baseDir
124
- : '/data/local/tmp';
127
+ const dir = isAndroidConfigured(browserOptions)
128
+ ? '/data/local/tmp'
129
+ : baseDir;
125
130
  seleniumOptions.addArguments(`--log-net-log=${dir}/chromeNetlog.json`);
126
131
  const level = browserOptions.netLogCaptureMode || 'IncludeSensitive';
127
132
  seleniumOptions.addArguments(`--net-log-capture-mode=${level}`);
@@ -133,13 +138,13 @@ export default function (seleniumOptions, browserOptions, options, baseDir) {
133
138
  '--remote-debugging-port=' + options.devToolsPort
134
139
  );
135
140
  } else {
136
- if (!browserOptions.noDefaultOptions) {
141
+ if (browserOptions.noDefaultOptions) {
142
+ log.info('Skip setting default options for Chrome');
143
+ } else {
137
144
  seleniumOptions.addArguments(defaultChromeOptions);
138
145
  seleniumOptions.addArguments(
139
146
  '--remote-debugging-port=' + options.devToolsPort
140
147
  );
141
- } else {
142
- log.info('Skip setting default options for Chrome');
143
148
  }
144
149
  }
145
150
 
@@ -4,7 +4,7 @@ import get from 'lodash.get';
4
4
  import intel from 'intel';
5
5
  const log = intel.getLogger('browsertime.connectivity.humble');
6
6
 
7
- class Humble {
7
+ export class Humble {
8
8
  constructor(options) {
9
9
  this.url = get(options.connectivity, 'humble.url');
10
10
  this.profile = options.connectivity.profile;
@@ -13,13 +13,13 @@ class Humble {
13
13
  async start(profile) {
14
14
  const library = this.url.startsWith('https') ? https : http;
15
15
  const res = await new Promise(resolve => {
16
- if (this.profile !== 'custom') {
17
- library.get(`${this.url}/api/${this.profile}`, resolve);
18
- } else {
16
+ if (this.profile === 'custom') {
19
17
  library.get(
20
18
  `${this.url}/api/custom?up=${profile.up}&down=${profile.down}&rtt=${profile.rtt}`,
21
19
  resolve
22
20
  );
21
+ } else {
22
+ library.get(`${this.url}/api/${this.profile}`, resolve);
23
23
  }
24
24
  });
25
25
 
@@ -30,10 +30,10 @@ class Humble {
30
30
  res.on('end', () => resolve(data));
31
31
  });
32
32
 
33
- if (res.statusCode !== 200) {
34
- log.error('Humble response: %s', data);
35
- } else {
33
+ if (res.statusCode === 200) {
36
34
  log.info('Switch Humble at %s to use profile %s', this.url, this.profile);
35
+ } else {
36
+ log.error('Humble response: %s', data);
37
37
  }
38
38
  }
39
39
 
@@ -50,12 +50,10 @@ class Humble {
50
50
  res.on('end', () => resolve(data));
51
51
  });
52
52
 
53
- if (res.statusCode !== 200) {
54
- log.error('Humble response: %s', data);
55
- } else {
53
+ if (res.statusCode === 200) {
56
54
  log.info('Humble throttling stopped successfully');
55
+ } else {
56
+ log.error('Humble response: %s', data);
57
57
  }
58
58
  }
59
59
  }
60
-
61
- export default Humble;
@@ -5,7 +5,7 @@ import {
5
5
  stop as throttleStop
6
6
  } from '@sitespeed.io/throttle';
7
7
  const log = intel.getLogger('browsertime.connectivity');
8
- import Humble from './humble.js';
8
+ import { Humble } from './humble.js';
9
9
  import { parseTrafficShapeConfig } from './trafficShapeParser.js';
10
10
 
11
11
  let humble;
@@ -4,7 +4,7 @@ import get from 'lodash.get';
4
4
  import intel from 'intel';
5
5
  import { timestamp as _timestamp } from '../../support/engineUtils.js';
6
6
  import { Statistics } from '../../support/statistics.js';
7
- import pathToFolder from '../../support/pathToFolder.js';
7
+ import { pathToFolder } from '../../support/pathToFolder.js';
8
8
  import { getConnectivitySettings } from '../../connectivity/index.js';
9
9
  import { formatMetric } from '../../support/util.js';
10
10
  const require = createRequire(import.meta.url);
@@ -60,7 +60,7 @@ function getNewResult(url, options) {
60
60
  * per iteration and store what's needed to disk.
61
61
  * @class
62
62
  */
63
- class Collector {
63
+ export class Collector {
64
64
  constructor(url, storageManager, options) {
65
65
  this.options = options;
66
66
  this.storageManager = storageManager;
@@ -520,5 +520,3 @@ class Collector {
520
520
  }
521
521
  }
522
522
  }
523
-
524
- export default Collector;
@@ -2,7 +2,7 @@ import { By } from 'selenium-webdriver';
2
2
  import intel from 'intel';
3
3
  const log = intel.getLogger('browsertime.command.addText');
4
4
 
5
- class AddText {
5
+ export class AddText {
6
6
  constructor(browser) {
7
7
  this.browser = browser;
8
8
  }
@@ -117,4 +117,3 @@ class AddText {
117
117
  }
118
118
  }
119
119
  }
120
- export default AddText;
@@ -1,7 +1,7 @@
1
1
  import intel from 'intel';
2
2
  import { Android, isAndroidConfigured } from '../../../android/index.js';
3
3
  const log = intel.getLogger('browsertime.command.android');
4
- export default class AndroidCommand {
4
+ export class AndroidCommand {
5
5
  constructor(options) {
6
6
  this.options = options;
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import intel from 'intel';
2
2
  const log = intel.getLogger('browsertime.command.cache');
3
- class Cache {
3
+ export class Cache {
4
4
  constructor(browser, browserName, extensionServer, cdp) {
5
5
  this.browser = browser;
6
6
  this.browserName = browserName;
@@ -45,4 +45,3 @@ class Cache {
45
45
  }
46
46
  }
47
47
  }
48
- export default Cache;
@@ -2,7 +2,7 @@ import intel from 'intel';
2
2
  const log = intel.getLogger('browsertime.command.devtoolsprotocol');
3
3
 
4
4
  // https://chromedevtools.github.io/devtools-protocol/
5
- class DevelopmentToolsProtocol {
5
+ export class ChromeDevelopmentToolsProtocol {
6
6
  constructor(engineDelegate, browserName) {
7
7
  this.engineDelegate = engineDelegate;
8
8
  this.browserName = browserName;
@@ -51,6 +51,14 @@ class DevelopmentToolsProtocol {
51
51
  }
52
52
  }
53
53
 
54
+ getRawClient() {
55
+ if (this.browserName === 'chrome' || this.browserName === 'edge') {
56
+ return this.engineDelegate.getCDPClient().getRawClient();
57
+ } else {
58
+ throw new Error('DevToolsProtocol only supported in Chrome and Edge');
59
+ }
60
+ }
61
+
54
62
  async send(command, arguments_) {
55
63
  if (this.browserName === 'chrome' || this.browserName === 'edge') {
56
64
  try {
@@ -70,4 +78,3 @@ class DevelopmentToolsProtocol {
70
78
  }
71
79
  }
72
80
  }
73
- export default DevelopmentToolsProtocol;
@@ -10,7 +10,7 @@ function addClick(js) {
10
10
  return script;
11
11
  }
12
12
 
13
- class Click {
13
+ export class Click {
14
14
  constructor(browser, pageCompleteCheck) {
15
15
  this.browser = browser;
16
16
  this.pageCompleteCheck = pageCompleteCheck;
@@ -269,4 +269,3 @@ class Click {
269
269
  }
270
270
  }
271
271
  }
272
- export default Click;
@@ -2,7 +2,7 @@ import intel from 'intel';
2
2
  const log = intel.getLogger('browsertime.command.debug');
3
3
  const delay = ms => new Promise(res => setTimeout(res, ms));
4
4
 
5
- class Debug {
5
+ export class Debug {
6
6
  constructor(browser, options) {
7
7
  this.browser = browser;
8
8
  this.options = options;
@@ -43,5 +43,3 @@ class Debug {
43
43
  }
44
44
  }
45
45
  }
46
-
47
- export default Debug;
@@ -1,6 +1,6 @@
1
1
  import intel from 'intel';
2
2
  const log = intel.getLogger('browsertime.command.javascript');
3
- class JavaScript {
3
+ export class JavaScript {
4
4
  constructor(browser, pageCompleteCheck) {
5
5
  this.browser = browser;
6
6
  this.pageCompleteCheck = pageCompleteCheck;
@@ -97,4 +97,3 @@ class JavaScript {
97
97
  }
98
98
  }
99
99
  }
100
- export default JavaScript;
@@ -3,14 +3,14 @@ import intel from 'intel';
3
3
  import get from 'lodash.get';
4
4
  import merge from 'lodash.merge';
5
5
  import { timestamp as _timestamp } from '../../../support/engineUtils.js';
6
- import Video from '../../../video/video.js';
7
- import pathToFolder from '../../../support/pathToFolder.js';
8
- import setOrangeBackground from '../../../video/screenRecording/setOrangeBackground.js';
6
+ import { Video } from '../../../video/video.js';
7
+ import { pathToFolder } from '../../../support/pathToFolder.js';
8
+ import { setOrangeBackground } from '../../../video/screenRecording/setOrangeBackground.js';
9
9
  import { filterWhitelisted } from '../../../support/userTiming.js';
10
10
  import { isAndroidConfigured, Android } from '../../../android/index.js';
11
- import TCPDump from '../../../support/tcpdump.js';
12
- import highlightLargestContentfulPaint from './util/lcpHighlightScript.js';
13
- import highlightLS from './util/lsHighlightScript.js';
11
+ import { TCPDump } from '../../../support/tcpdump.js';
12
+ import { lcpHighlightScript as highlightLargestContentfulPaint } from './util/lcpHighlightScript.js';
13
+ import { clsHighlightScript as highlightLS } from './util/lsHighlightScript.js';
14
14
  const delay = ms => new Promise(res => setTimeout(res, ms));
15
15
  const log = intel.getLogger('browsertime.command.measure');
16
16
 
@@ -27,7 +27,7 @@ function getNewResult() {
27
27
  };
28
28
  }
29
29
 
30
- class Measure {
30
+ export class Measure {
31
31
  constructor(
32
32
  browser,
33
33
  index,
@@ -105,10 +105,10 @@ class Measure {
105
105
  _error(message) {
106
106
  // If we already are measuring a page, associate the error woth that page
107
107
  if (this.areWeMeasuring === true) {
108
- if (!this.result[this.numberOfMeasuredPages].error) {
109
- this.result[this.numberOfMeasuredPages].error = [message];
110
- } else {
108
+ if (this.result[this.numberOfMeasuredPages].error) {
111
109
  this.result[this.numberOfMeasuredPages].error.push(message);
110
+ } else {
111
+ this.result[this.numberOfMeasuredPages].error = [message];
112
112
  }
113
113
  } else {
114
114
  // If we have tested pages before, but not in the making of
@@ -360,10 +360,10 @@ class Measure {
360
360
  this.result[this.numberOfMeasuredPages].alias
361
361
  ) {
362
362
  const alias = this.result[this.numberOfMeasuredPages].alias;
363
- if (!aliasAndUrl[alias]) {
364
- aliasAndUrl[alias] = url;
365
- } else {
363
+ if (aliasAndUrl[alias]) {
366
364
  url = aliasAndUrl[alias];
365
+ } else {
366
+ aliasAndUrl[alias] = url;
367
367
  }
368
368
  }
369
369
 
@@ -522,5 +522,3 @@ class Measure {
522
522
  this.areWeMeasuring = false;
523
523
  }
524
524
  }
525
-
526
- export default Measure;
@@ -1,4 +1,4 @@
1
- export default class Meta {
1
+ export class Meta {
2
2
  constructor() {}
3
3
 
4
4
  setDescription(text) {
@@ -1,7 +1,7 @@
1
1
  import intel from 'intel';
2
2
  const log = intel.getLogger('browsertime.command.navigation');
3
3
 
4
- export default class Navigation {
4
+ export class Navigation {
5
5
  constructor(browser, pageCompleteCheck) {
6
6
  this.browser = browser;
7
7
  this.pageCompleteCheck = pageCompleteCheck;
@@ -1,4 +1,4 @@
1
- export default class Screenshot {
1
+ export class Screenshot {
2
2
  constructor(screenshotManager, browser, index) {
3
3
  this.screenshotManager = screenshotManager;
4
4
  this.browser = browser;
@@ -1,7 +1,7 @@
1
1
  import intel from 'intel';
2
2
  const log = intel.getLogger('browsertime.command.scroll');
3
3
  const delay = ms => new Promise(res => setTimeout(res, ms));
4
- export default class Scroll {
4
+ export class Scroll {
5
5
  constructor(browser, options) {
6
6
  this.browser = browser;
7
7
  this.options = options;
@@ -1,7 +1,7 @@
1
1
  import intel from 'intel';
2
2
  const log = intel.getLogger('browsertime.command.select');
3
3
 
4
- export default class Select {
4
+ export class Select {
5
5
  constructor(browser) {
6
6
  this.browser = browser;
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import intel from 'intel';
2
2
  const log = intel.getLogger('browsertime.command.set');
3
3
 
4
- export default class Set {
4
+ export class Set {
5
5
  constructor(browser) {
6
6
  this.browser = browser;
7
7
  }
@@ -47,7 +47,7 @@ export class StopWatch {
47
47
  }
48
48
  }
49
49
 
50
- export default class Watch {
50
+ export class Watch {
51
51
  constructor(measure) {
52
52
  this.measure = measure;
53
53
  }
@@ -1,7 +1,8 @@
1
1
  import intel from 'intel';
2
+ import { By } from 'selenium-webdriver';
2
3
  const log = intel.getLogger('browsertime.command.switch');
3
4
 
4
- export default class Switch {
5
+ export class Switch {
5
6
  constructor(browser, pageCompleteCheck, navigate) {
6
7
  this.browser = browser;
7
8
  this.pageCompleteCheck = pageCompleteCheck;
@@ -23,6 +24,48 @@ export default class Switch {
23
24
  }
24
25
  }
25
26
 
27
+ /**
28
+ * Switch to frame by xpath
29
+ * @param {*} xpath
30
+ */
31
+ async toFrameByXpath(xpath) {
32
+ const driver = this.browser.getDriver();
33
+ try {
34
+ const element = await driver.findElement(By.xpath(xpath));
35
+ if (element) {
36
+ await driver.switchTo().frame(element);
37
+ } else {
38
+ log.error('Could not find frame using xpath %s ', xpath);
39
+ throw new Error(`Could not find frame using xpath ${xpath}`);
40
+ }
41
+ } catch (error) {
42
+ log.error('Could not switch to frame using xpath %s ', xpath);
43
+ log.verbose(error);
44
+ throw new Error(`Could not switch to frame using xpath ${xpath}`);
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Switch to frame by xpath
50
+ * @param {*} xpath
51
+ */
52
+ async toFrameBySelector(selector) {
53
+ const driver = this.browser.getDriver();
54
+ try {
55
+ const element = await driver.findElement(By.css(selector));
56
+ if (element) {
57
+ await driver.switchTo().frame(element);
58
+ } else {
59
+ log.error('Could not find frame using selector%s ', selector);
60
+ throw new Error(`Could not find frame using selector ${selector}`);
61
+ }
62
+ } catch (error) {
63
+ log.error('Could not switch to frame using selector %s ', selector);
64
+ log.verbose(error);
65
+ throw new Error(`Could not switch to frame using selector${selector}`);
66
+ }
67
+ }
68
+
26
69
  /**
27
70
  * Switch to a window by name
28
71
  * @param {*} name
@@ -1,4 +1,4 @@
1
- export default `
1
+ export const lcpHighlightScript = `
2
2
  return (function(color) {
3
3
  const observer = new PerformanceObserver(list => {});
4
4
  observer.observe({ type: 'largest-contentful-paint', buffered: true });
@@ -1,4 +1,4 @@
1
- export default `
1
+ export const clsHighlightScript = `
2
2
  (function(options) {
3
3
  const rectColor = options.color;
4
4
  const limit = options.limit;
@@ -3,7 +3,7 @@ import intel from 'intel';
3
3
  const log = intel.getLogger('browsertime.command.wait');
4
4
  const delay = ms => new Promise(res => setTimeout(res, ms));
5
5
 
6
- export default class Wait {
6
+ export class Wait {
7
7
  constructor(browser, pageCompleteCheck) {
8
8
  this.browser = browser;
9
9
  this.pageCompleteCheck = pageCompleteCheck;
@@ -4,10 +4,10 @@ import merge from 'lodash.merge';
4
4
  import getPort, { portNumbers } from 'get-port';
5
5
  import { execaCommand as command } from 'execa';
6
6
  import get from 'lodash.get';
7
- import StorageManager from '../../support/storageManager.js';
8
- import Firefox from '../../firefox/webdriver/firefox.js';
9
- import Chromium from '../../chrome/webdriver/chromium.js';
10
- import Safari from '../../safari/webdriver/safari.js';
7
+ import { StorageManager } from '../../support/storageManager.js';
8
+ import { Firefox } from '../../firefox/webdriver/firefox.js';
9
+ import { Chromium } from '../../chrome/webdriver/chromium.js';
10
+ import { Safari } from '../../safari/webdriver/safari.js';
11
11
  import {
12
12
  addConnectivity,
13
13
  removeConnectivity
@@ -18,14 +18,14 @@ import {
18
18
  getMainDocumentTimings,
19
19
  addExtraFieldsToHar
20
20
  } from '../../support/har/index.js';
21
- import XVFB from '../../support/xvfb.js';
22
- import Gnirehtet from '../../android/gnirehtet.js';
23
- import Iteration from './iteration.js';
24
- import Collector from './collector.js';
21
+ import { XVFB } from '../../support/xvfb.js';
22
+ import { Gnirehtet } from '../../android/gnirehtet.js';
23
+ import { Iteration } from './iteration.js';
24
+ import { Collector } from './collector.js';
25
25
  import { Android, isAndroidConfigured } from '../../android/index.js';
26
- import RootedDevice from '../../android/root.js';
27
- import run from './run.js';
28
- import IOSRecorder from '../../video/screenRecording/ios/iosRecorder.js';
26
+ import { RootedDevice } from '../../android/root.js';
27
+ import { run } from './run.js';
28
+ import { IOSRecorder } from '../../video/screenRecording/ios/iosRecorder.js';
29
29
  import { loadPrePostScripts, loadScript } from '../../support/engineUtils.js';
30
30
  const log = intel.getLogger('browsertime');
31
31
  const defaults = {
@@ -45,7 +45,7 @@ function shouldDelay(index, total, delay) {
45
45
  * Create a new Browsertime Engine.
46
46
  * @class
47
47
  */
48
- export default class Engine {
48
+ export class Engine {
49
49
  constructor(options) {
50
50
  this.options = merge({}, defaults, options);
51
51
  if (log.isEnabledFor(log.DEBUG)) {