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
package/CHANGELOG.md CHANGED
@@ -1,12 +1,22 @@
1
1
  # Browsertime changelog (we do [semantic versioning](https://semver.org))
2
2
 
3
- ## 17.0.0 - UNRELEASED
3
+ ## 17.1.0 - 2022-02-24
4
+
5
+ ### Added
6
+ * Fix visual-complete progress calculations to not use fuzz/slop, thank you [Gregory Mierzwinski](https://github.com/gmierz) for PR [#1902](https://github.com/sitespeedio/browsertime/pull/1902).
7
+ * Expose chrome-remote-interface client to scripting. This makes it so much easier to run whatever CDP command. Get the raw version `commands.cdp.getRawClient();`. See PR [#1905](https://github.com/sitespeedio/browsertime/pull/1905) for a concrete example until we update the documentation.
8
+ ### Fixed
9
+ * Update to new Chrome HAR [#1906](https://github.com/sitespeedio/browsertime/pull/1906).
10
+ * Fix flushing DNS on Ubuntu 22.04 [#1907](https://github.com/sitespeedio/browsertime/pull/1907).
11
+ ## 17.0.0 - 2022-02-10
4
12
 
5
13
  ### Breaking changes
6
- * We moved the project to be a [pure ESM package](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) [#1859](https://github.com/sitespeedio/browsertime/pull/1859). That helps us keep up to date with dependencies that already did the move and make sure we can always use the latest version of our dependencies.
14
+ The project was transitioned to a [pure ESM package](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) [#1859](https://github.com/sitespeedio/browsertime/pull/1859), allowing us to stay current with dependencies that have made the same transition and ensuring the ability to always utilize the latest versions of our dependencies. This is important for us and will make the project easier to maintain.
15
+
7
16
 
8
17
  #### CLI users
9
18
  If you are a command line user and use scripting, you will need to do a change to your scripts or add a extra configuration.
19
+
10
20
  The new browsertime version treat all JavaScript files that ends with *.js* as ESM modules, that means your old script files will not work out of the box. There's a couple of fixes for that:
11
21
 
12
22
  **The best fix**:
@@ -25,11 +35,13 @@ export default async function (context, commands) {
25
35
  }
26
36
  ```
27
37
 
28
- If you have more complicated scripts, follow the [ESM package guide](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c).
38
+ If you have more complicated scripts, follow the [ESM package guide](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c).
39
+
40
+ This is the best fix and will woirk 100% of the time.
29
41
 
30
- **The quick fix**: Rename your *.js* to *.cjs* that way NodeJS will treat your file as a common JS file and everthing will just work. For example if you have a file names `login.js` you can rename that to `login.cjs` and make sure you load that new file.
42
+ **The quick fix**: Rename your *.js* to *.cjs* that way NodeJS will treat your file as a common JS file and everything will just work. For example if you have a file names `login.js` you can rename that to `login.cjs` and make sure you load that new file.
31
43
 
32
- **Another quick fix alternative**: Add `--cjs` as a parameter to your test. That way the scripting file will be treated as a commonjs file. This is a hack, so to make sure it works, the user that runs Browsertime need to have write privileges to the folder where you have your scripting files.
44
+ **Another quick fix alternative**: As a last alternative add `--cjs` as a parameter to your test. That way the scripting file will be treated as a commonjs file. This is a hack, so to make sure it works, the user that runs Browsertime need to have write privileges to the folder where you have your scripting files. Browsertime will create a package.json file on the same levels as yoru script file. If you already have a package.json there, it will be overwritten.
33
45
 
34
46
  #### Non cli users
35
47
  If you import Browsertime in NodeJS we changed how you do your import.
@@ -50,7 +62,7 @@ Read [Sindre Sorhus Pure ESM package guide](https://gist.github.com/sindresorhus
50
62
 
51
63
  * We moved to use a new [Visual Metrics script](https://github.com/sitespeedio/browsertime/blob/main/browsertime/visualmetrics-portable.py) as default contributed by [Gregory Mierzwinski](https://github.com/gmierz) that do _not_ use ImageMagick. Mozilla has used this script for many months and we have internally used it in our test infrastructure since it was first released.
52
64
 
53
- If you run Browsertime direct using NodeJs (and not using Docker) you need to install two new Python dependencies OpenCV-Python Numpy.
65
+ If you run Browsertime direct using NodeJs (and not using Docker) you need to install two new Python dependencies `OpenCV-Python Numpy`.
54
66
 
55
67
  ```
56
68
  python -m pip install --user OpenCV-Python Numpy
@@ -59,16 +71,21 @@ python -m pip install --user OpenCV-Python Numpy
59
71
  This is pretty cool because it makes dependencies easier to install on all platforms + the script has also been cleaned up so its easier for us to maintain.
60
72
 
61
73
  ### Added
62
- * Chrome and Chromedriver 106 [#1853](https://github.com/sitespeedio/browsertime/pull/1853).
63
- * Selenium 4.5 [#1852](https://github.com/sitespeedio/browsertime/pull/1852).
64
- * Updated dependencies: edgedriver, execa, days, find-up, get-ports, jimp, yargs [#1860](https://github.com/sitespeedio/browsertime/pull/1860)
65
- * Updated to Chrome 107 in the Docker container.
66
- * Updated to NodeJS 18 in the Docker container.
67
-
74
+ * Selenium 4.8.
75
+ * Updated dependencies: execa, days, find-up, get-ports, jimp, yargs [#1860](https://github.com/sitespeedio/browsertime/pull/1860)
76
+ * Updated to Chrome, Firefox and Edge 109 in the Docker container. Also updated all drivers.
77
+ * Updated to NodeJS 18 and Ubuntu 22.04 in the Docker container.
78
+ * Get CPU metrics using Glean on Firefox, thank you [afinder-mozilla](https://github.com/afinder-mozilla) for PR [#1875](https://github.com/sitespeedio/browsertime/pull/1875)
79
+ * Provide active tab id to gecko profiler StartProfiler API in Firefox, thank you [Nazım Can Altınova](https://github.com/canova) for PR [#1874](https://github.com/sitespeedio/browsertime/pull/1874).
80
+ * There's two new methods to switch to frame: `switch.toFrameByXpath(xpath)` and `switch.toFrameBySelector(selector)` [#1880](https://github.com/sitespeedio/browsertime/pull/1880).
81
+ * Add a timeout to gecko profiler gzipping phase, thank you [Nazım Can Altınova](https://github.com/canova) for PR [#1896](https://github.com/sitespeedio/browsertime/pull/1896)
82
+ * Pin CPU freq to fastest for Samsung A51 (if you have a rooted device) [#1895](https://github.com/sitespeedio/browsertime/pull/1895).
68
83
  ### Fixed
69
84
  * Pause the gecko profiler before starting to collect the profile data, thank you [Nazım Can Altınova](https://github.com/canova) for PR [#1856](https://github.com/sitespeedio/browsertime/pull/1856).
70
85
 
71
- * All Android configurations has been moved to an Android group. That makes it easier when you run --help and can see all Android configuration grouped together. For example `--androidBatteryTemperature` is now `--android.batteryTemperatureLimit`. Old names will still work. [#1865](https://github.com/sitespeedio/browsertime/pull/1865)
86
+ * All Android configurations has been moved to an Android group. That makes it easier when you run --help and can see all Android configuration grouped together. For example `--androidBatteryTemperature` is now `--android.batteryTemperatureLimit`. Old names will still work but are deprecated [#1865](https://github.com/sitespeedio/browsertime/pull/1865).
87
+
88
+ * Updated to Chromedriver 110 to work with Android 13 [#1894](https://github.com/sitespeedio/browsertime/pull/1894).
72
89
 
73
90
  ## 16.17.0 - 2022-09-27
74
91
  ### Added
@@ -5,15 +5,15 @@ import set from 'lodash.set';
5
5
  import intel from 'intel';
6
6
  import { existsSync, mkdirSync } from 'node:fs';
7
7
  import { resolve, relative } from 'node:path';
8
- import Engine from '../lib/core/engine/index.js';
8
+ import { Engine } from '../lib/core/engine/index.js';
9
9
  import {
10
10
  findAndParseScripts,
11
11
  allScriptCategories,
12
12
  getScriptsForCategories
13
13
  } from '../lib/support/browserScript.js';
14
- import logging from '../lib/support/logging.js';
14
+ import { configure } from '../lib/support/logging.js';
15
15
  import { parseCommandLine } from '../lib/support/cli.js';
16
- import StorageManager from '../lib/support/storageManager.js';
16
+ import { StorageManager } from '../lib/support/storageManager.js';
17
17
  import { loadScript } from '../lib/support/engineUtils.js';
18
18
  import { isAndroidConfigured } from '../lib/android/index.js';
19
19
 
@@ -154,7 +154,7 @@ async function run(urls, options) {
154
154
  }
155
155
 
156
156
  let cliResult = parseCommandLine();
157
- logging(cliResult.options);
157
+ configure(cliResult.options);
158
158
 
159
159
  /*
160
160
  Each url can be:
@@ -3,8 +3,8 @@ import merge from 'lodash.merge';
3
3
  import yargs from 'yargs';
4
4
  import { hideBin } from 'yargs/helpers';
5
5
 
6
- import Engine from '../lib/core/engine/index.js';
7
- import logging from '../lib/support/logging.js';
6
+ import { Engine } from '../lib/core/engine/index.js';
7
+ import { configure as logging } from '../lib/support/logging.js';
8
8
 
9
9
  async function runBrowsertime() {
10
10
  let yargsInstance = yargs(hideBin(process.argv));
@@ -372,7 +372,7 @@ def video_to_frames(
372
372
  viewport_retries,
373
373
  viewport_min_height,
374
374
  viewport_min_width,
375
- full_resolution
375
+ full_resolution,
376
376
  ):
377
377
  """Extract the video frames"""
378
378
  global client_viewport
@@ -413,9 +413,7 @@ def video_to_frames(
413
413
  if orange_file is not None:
414
414
  remove_frames_before_orange(dir, orange_file)
415
415
  remove_orange_frames(dir, orange_file)
416
- find_render_start(
417
- dir, orange_file, cropped, is_mobile
418
- )
416
+ find_render_start(dir, orange_file, cropped, is_mobile)
419
417
  adjust_frame_times(dir)
420
418
  eliminate_duplicate_frames(dir, cropped, is_mobile)
421
419
  crop_viewport(dir)
@@ -508,6 +506,7 @@ def find_recording_platform(video):
508
506
 
509
507
  return is_mobile
510
508
 
509
+
511
510
  def remove_frames_before_orange(directory, orange_file):
512
511
  """Remove stray frames from the start of the video"""
513
512
  frames = sorted(glob.glob(os.path.join(directory, "video-*.png")))
@@ -533,6 +532,7 @@ def remove_frames_before_orange(directory, orange_file):
533
532
  logging.debug("Removing pre-orange frame %s", frame)
534
533
  os.remove(frame)
535
534
 
535
+
536
536
  def remove_orange_frames(directory, orange_file):
537
537
  """Remove orange frames from the beginning of the video"""
538
538
  frames = sorted(glob.glob(os.path.join(directory, "video-*.png")))
@@ -708,6 +708,7 @@ def find_video_viewport(
708
708
 
709
709
  return viewport, cropped
710
710
 
711
+
711
712
  def adjust_frame_times(directory):
712
713
  offset = None
713
714
  frames = sorted(glob.glob(os.path.join(directory, "video-*.png")))
@@ -728,6 +729,7 @@ def adjust_frame_times(directory):
728
729
  dest = os.path.join(directory, "ms_{0:06d}.png".format(new_time))
729
730
  os.rename(frame, dest)
730
731
 
732
+
731
733
  def find_render_start(directory, orange_file, cropped, is_mobile):
732
734
  logging.debug("Finding Render Start...")
733
735
  try:
@@ -902,6 +904,7 @@ def eliminate_duplicate_frames(directory, cropped, is_mobile):
902
904
  except BaseException:
903
905
  logging.exception("Error processing frames for duplicates")
904
906
 
907
+
905
908
  def crop_viewport(directory):
906
909
  if client_viewport is not None:
907
910
  try:
@@ -928,7 +931,9 @@ def crop_viewport(directory):
928
931
  def get_decimate_filter():
929
932
  decimate = None
930
933
  try:
931
- filters = subprocess.check_output(["ffmpeg", "-filters"], stderr=subprocess.STDOUT, encoding="UTF-8")
934
+ filters = subprocess.check_output(
935
+ ["ffmpeg", "-filters"], stderr=subprocess.STDOUT, encoding="UTF-8"
936
+ )
932
937
  lines = filters.split("\n")
933
938
  match = re.compile(
934
939
  r"(?P<filter>[\w]*decimate).*V->V.*Remove near-duplicate frames"
@@ -1005,6 +1010,7 @@ def is_color_frame(file, color_file):
1005
1010
  frame_cache[file][color_file] = bool(match)
1006
1011
  return match
1007
1012
 
1013
+
1008
1014
  def colors_are_similar(a, b, threshold=15):
1009
1015
  similar = True
1010
1016
  sum = 0
@@ -1073,6 +1079,7 @@ def generate_orange_png(orange_file):
1073
1079
  except BaseException:
1074
1080
  logging.exception("Error generating orange png " + orange_file)
1075
1081
 
1082
+
1076
1083
  ##########################################################################
1077
1084
  # Histogram calculations
1078
1085
  ##########################################################################
@@ -1190,6 +1197,7 @@ def convert_to_jpeg(directory, quality):
1190
1197
 
1191
1198
  logging.debug("Done converting video frames to JPEG")
1192
1199
 
1200
+
1193
1201
  ##########################################################################
1194
1202
  # Visual Metrics
1195
1203
  ##########################################################################
@@ -1266,9 +1274,7 @@ def calculate_visual_metrics(
1266
1274
  viewport = hero_data["viewport"]
1267
1275
  hero_timings = []
1268
1276
  for hero in hero_data["heroes"]:
1269
- hero_time = calculate_hero_time(
1270
- progress, dirs, hero, viewport
1271
- )
1277
+ hero_time = calculate_hero_time(progress, dirs, hero, viewport)
1272
1278
  if hero_time is not None:
1273
1279
  hero_timings.append(
1274
1280
  {
@@ -1352,30 +1358,34 @@ def calculate_visual_progress(histograms):
1352
1358
 
1353
1359
 
1354
1360
  def calculate_frame_progress(histogram, start, final):
1361
+ """Calculate the progress percentage of a given frame histogram.
1362
+
1363
+ This method finds the visually-complete progress by taking a sum of
1364
+ all the differences in the histogram between the current frame, and the
1365
+ final frame. The initial/first frame is used to remove values that are
1366
+ consitent between the first, and final frame (i.e. it's a baseline).
1367
+
1368
+ Note that this method should not be using a slop/fuzz because we aren't
1369
+ looking at individual pixel intensities which is where the fuzz can be
1370
+ found. Within individual channels, we hit an issue where we cannot tell
1371
+ if a value in the red channel is purely from a red colour in the image, or
1372
+ if it's mixed with other colours such as grey (e.g. red with rbg(240,0,0),
1373
+ and light grey with rgb(245,245,245)).
1374
+ """
1355
1375
  total = 0
1356
1376
  matched = 0
1357
- slop = 5 # allow for matching slight color variations
1358
- channels = ["r", "g", "b"]
1359
- for channel in channels:
1360
- channel_total = 0
1361
- channel_matched = 0
1362
- buckets = 256
1363
- available = [0 for i in range(buckets)]
1364
- for i in range(buckets):
1365
- available[i] = abs(histogram[channel][i] - start[channel][i])
1366
- for i in range(buckets):
1367
- target = abs(final[channel][i] - start[channel][i])
1368
- if target:
1369
- channel_total += target
1370
- low = max(0, i - slop)
1371
- high = min(buckets, i + slop)
1372
- for j in range(low, high):
1373
- this_match = min(target, available[j])
1374
- available[j] -= this_match
1375
- channel_matched += this_match
1376
- target -= this_match
1377
- total += channel_total
1378
- matched += channel_matched
1377
+ for channel in ("r", "g", "b"):
1378
+ for pixel_ind in range(256):
1379
+ curr = histogram[channel][pixel_ind]
1380
+ init = start[channel][pixel_ind]
1381
+ target = final[channel][pixel_ind]
1382
+
1383
+ curr_diff = abs(curr - init)
1384
+ target_diff = abs(target - init)
1385
+
1386
+ matched += min(curr_diff, target_diff)
1387
+ total += target_diff
1388
+
1379
1389
  progress = (float(matched) / float(total)) if total else 1
1380
1390
  return math.floor(progress * 100)
1381
1391
 
@@ -1609,16 +1619,14 @@ def calculate_hero_time(progress, directory, hero, viewport):
1609
1619
  def check_config():
1610
1620
  ok = True
1611
1621
 
1612
-
1613
1622
  if get_decimate_filter() is not None:
1614
- logging.debug('FFMPEG found')
1623
+ logging.debug("FFMPEG found")
1615
1624
  else:
1616
1625
  print("ffmpeg: FAIL")
1617
1626
  ok = False
1618
1627
 
1619
-
1620
1628
  if sys.version_info >= (3, 6):
1621
- logging.debug('Python 3.6+ found')
1629
+ logging.debug("Python 3.6+ found")
1622
1630
  else:
1623
1631
  print("Python 3.6+: FAIL")
1624
1632
  ok = False
@@ -1626,33 +1634,31 @@ def check_config():
1626
1634
  try:
1627
1635
  import numpy as np
1628
1636
 
1629
- logging.debug('Numpy found')
1637
+ logging.debug("Numpy found")
1630
1638
  except BaseException:
1631
1639
  print("Numpy: FAIL")
1632
1640
  ok = False
1633
1641
 
1634
-
1635
1642
  try:
1636
1643
  import cv2
1637
-
1638
- logging.debug('OpenCV-Python found')
1644
+
1645
+ logging.debug("OpenCV-Python found")
1639
1646
  except BaseException:
1640
1647
  print("OpenCV-Python: FAIL")
1641
1648
  ok = False
1642
1649
 
1643
-
1644
1650
  try:
1645
1651
  from PIL import Image, ImageCms, ImageDraw, ImageOps # noqa
1646
1652
 
1647
- logging.debug('Pillow found')
1653
+ logging.debug("Pillow found")
1648
1654
  except BaseException:
1649
1655
  print("Pillow: FAIL")
1650
1656
  ok = False
1651
1657
 
1652
-
1653
1658
  try:
1654
1659
  from ssim import compute_ssim # noqa
1655
- logging.debug('SSIM found')
1660
+
1661
+ logging.debug("SSIM found")
1656
1662
  except BaseException:
1657
1663
  print("SSIM: FAIL")
1658
1664
  ok = False
@@ -1662,8 +1668,10 @@ def check_config():
1662
1668
 
1663
1669
  def check_process(command, output):
1664
1670
  ok = False
1665
- try:
1666
- out = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True, encoding="UTF-8")
1671
+ try:
1672
+ out = subprocess.check_output(
1673
+ command, stderr=subprocess.STDOUT, shell=True, encoding="UTF-8"
1674
+ )
1667
1675
  if out.find(output) > -1:
1668
1676
  ok = True
1669
1677
  except BaseException:
@@ -1834,11 +1842,7 @@ def main():
1834
1842
 
1835
1843
  options = parser.parse_args()
1836
1844
 
1837
- if (
1838
- not options.check
1839
- and not options.dir
1840
- and not options.video
1841
- ):
1845
+ if not options.check and not options.dir and not options.video:
1842
1846
  parser.error(
1843
1847
  "A video, Directory of images or histograms file needs to be provided.\n\n"
1844
1848
  "Use -h to see available options"
@@ -1910,7 +1914,7 @@ def main():
1910
1914
  options.viewportminwidth,
1911
1915
  options.full,
1912
1916
  )
1913
-
1917
+
1914
1918
  # Calculate the histograms and visual metrics
1915
1919
  calculate_histograms(directory, histogram_file, options.force)
1916
1920
  metrics = calculate_visual_metrics(
package/index.js CHANGED
@@ -12,5 +12,5 @@ export const browserScripts = {
12
12
  findAndParseScripts
13
13
  };
14
14
 
15
- export { default as BrowsertimeEngine } from './lib/core/engine/index.js';
16
- export { default as configureLogging } from './lib/support/logging.js';
15
+ export { Engine as BrowsertimeEngine } from './lib/core/engine/index.js';
16
+ export { configure as configureLogging } from './lib/support/logging.js';
@@ -3,7 +3,7 @@ import intel from 'intel';
3
3
  const log = intel.getLogger('browsertime.gnirehtet');
4
4
  const delay = ms => new Promise(response => setTimeout(response, ms));
5
5
 
6
- class Gnirehtet {
6
+ export class Gnirehtet {
7
7
  constructor(options) {
8
8
  this.options = options;
9
9
  }
@@ -65,4 +65,3 @@ class Gnirehtet {
65
65
  return delay(2000);
66
66
  }
67
67
  }
68
- export default Gnirehtet;
@@ -11,7 +11,7 @@ const animationsToStop = [
11
11
  'window_animation_scale'
12
12
  ];
13
13
 
14
- class RootedDevice {
14
+ export class RootedDevice {
15
15
  constructor(androidClient) {
16
16
  this.client = androidClient;
17
17
  }
@@ -83,6 +83,29 @@ class RootedDevice {
83
83
  }
84
84
  }
85
85
 
86
+ async setCPUPerformanceSamsungA51() {
87
+ // Octa-core (4x2.3 GHz Cortex-A73 & 4x1.7 GHz Cortex-A53)
88
+ // See values by
89
+ // cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies
90
+ // cat /sys/devices/system/cpu/cpufreq/policy4/scaling_available_frequencies
91
+
92
+ await this.client._runAsRoot(
93
+ 'echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor'
94
+ );
95
+
96
+ await this.client._runAsRoot(
97
+ 'echo performance > /sys/devices/system/cpu/cpufreq/policy4/scaling_governor'
98
+ );
99
+
100
+ await this.client._runAsRoot(
101
+ 'echo 1742000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq'
102
+ );
103
+
104
+ return this.client._runAsRoot(
105
+ 'echo 2314000 > /sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq'
106
+ );
107
+ }
108
+
86
109
  async setCPUPerformancePixel2() {
87
110
  // MSM8998 (4x 2.35GHz, 4x 1.9GHz)
88
111
  // values obtained from:
@@ -166,6 +189,11 @@ class RootedDevice {
166
189
  );
167
190
  }
168
191
 
192
+ async setGPUPerformanceSamsungA51() {
193
+ // Mali-G72 MP3 (3 @ 850 MHz)
194
+ // Missing info on how to set the GPU
195
+ }
196
+
169
197
  async start() {
170
198
  await this.stopServices();
171
199
  await this.stopAnimations();
@@ -178,19 +206,34 @@ class RootedDevice {
178
206
  `getprop ro.product.model`
179
207
  );
180
208
 
181
- if (model === 'Moto G (5)') {
182
- log.info('Set CPU and GPU performance settings for Moto G5');
183
- await this.setCPUPerformanceMotoG5();
184
- await this.setGPUPerformanceMotoG5();
185
- } else if (model === 'Pixel 2') {
186
- log.info('Set CPU and GPU performance settings for Pixel 2');
187
- await this.setCPUPerformancePixel2();
188
- await this.setGPUPerformancePixel2();
189
- } else {
190
- log.info(
191
- 'No specific CPU/GPU settings for %s - you can help out by creating a PR at https://github.com/sitespeedio/browsertime for your phone',
192
- model
193
- );
209
+ switch (model) {
210
+ case 'Moto G (5)': {
211
+ log.info('Set CPU and GPU performance settings for Moto G5');
212
+ await this.setCPUPerformanceMotoG5();
213
+ await this.setGPUPerformanceMotoG5();
214
+
215
+ break;
216
+ }
217
+ case 'Pixel 2': {
218
+ log.info('Set CPU and GPU performance settings for Pixel 2');
219
+ await this.setCPUPerformancePixel2();
220
+ await this.setGPUPerformancePixel2();
221
+
222
+ break;
223
+ }
224
+ case 'SM-A515F': {
225
+ // Samsung A51
226
+ await this.setCPUPerformanceSamsungA51();
227
+ await this.setGPUPerformanceSamsungA51();
228
+
229
+ break;
230
+ }
231
+ default: {
232
+ log.info(
233
+ 'No specific CPU/GPU settings for %s - you can help out by creating a PR at https://github.com/sitespeedio/browsertime for your phone',
234
+ model
235
+ );
236
+ }
194
237
  }
195
238
  }
196
239
 
@@ -199,5 +242,3 @@ class RootedDevice {
199
242
  return this.startAnimations();
200
243
  }
201
244
  }
202
-
203
- export default RootedDevice;
@@ -3,7 +3,7 @@ import CDP from 'chrome-remote-interface';
3
3
  import btoa from 'btoa';
4
4
  const log = intel.getLogger('browsertime.chrome.cdp');
5
5
  import { toArray } from '../support/util.js';
6
- import defaultTraceCategories from './settings/traceCategories.js';
6
+ import { traceCategories as defaultTraceCategories } from './settings/traceCategories.js';
7
7
 
8
8
  const MIME_TYPE_MATCHERS = [
9
9
  [/^text\/html/, 'html'],
@@ -20,7 +20,7 @@ function getContentType(mimeType) {
20
20
  return MIME_TYPE_MATCHERS.find(matcher => matcher[0].test(mimeType))[1];
21
21
  }
22
22
 
23
- class ChromeDevtoolsProtocol {
23
+ export class ChromeDevtoolsProtocol {
24
24
  constructor(options) {
25
25
  this.options = options;
26
26
  this.chrome = options.chrome || {};
@@ -157,6 +157,10 @@ class ChromeDevtoolsProtocol {
157
157
  });
158
158
  }
159
159
 
160
+ getRawClient() {
161
+ return this.cdpClient;
162
+ }
163
+
160
164
  async setRequestHeaders(requestHeaders) {
161
165
  // Our cli don't validate parameters
162
166
  // so -run will become -r etc
@@ -234,4 +238,3 @@ class ChromeDevtoolsProtocol {
234
238
  }
235
239
  }
236
240
  }
237
- export default ChromeDevtoolsProtocol;
package/lib/chrome/har.js CHANGED
@@ -5,7 +5,7 @@ const log = intel.getLogger('browsertime.chrome');
5
5
  import { addBrowser } from '../support/har/index.js';
6
6
  const { Type } = logging;
7
7
 
8
- export default async function (
8
+ export async function getHar(
9
9
  runner,
10
10
  result,
11
11
  index,
@@ -1,6 +1,6 @@
1
1
  import get from 'lodash.get';
2
2
 
3
- export default function (result, options) {
3
+ export function longTaskMetrics(result, options) {
4
4
  let totalDurationFirstPaint = 0;
5
5
  let totalDurationFirstContentFulPaint = 0;
6
6
  let totalDurationLargestContentFulPaint = 0;
@@ -11,7 +11,7 @@ function slowestFirst(a, b) {
11
11
  return b.value - a.value;
12
12
  }
13
13
 
14
- export default async (tracelog, url) => {
14
+ export async function parseCPUTrace(tracelog, url) {
15
15
  try {
16
16
  log.debug('Start parse Chrome trace log using Tracium.');
17
17
  const tasks = computeMainThreadTasks(tracelog, {
@@ -87,4 +87,4 @@ export default async (tracelog, url) => {
87
87
  );
88
88
  return {};
89
89
  }
90
- };
90
+ }
@@ -3,7 +3,7 @@
3
3
  * see https://github.com/GoogleChrome/chrome-launcher/blob/master/docs/chrome-flags-for-tools.md
4
4
  * https://peter.sh/experiments/chromium-command-line-switches/
5
5
  */
6
- export default [
6
+ export const chromeAndroidOptions = [
7
7
  '--disable-fre',
8
8
  // : Disable reporting to UMA, but allows for collection
9
9
  '--metrics-recording-only',
@@ -1,6 +1,6 @@
1
1
  // See https://github.com/GoogleChrome/chrome-launcher/blob/master/docs/chrome-flags-for-tools.md
2
2
  // https://peter.sh/experiments/chromium-command-line-switches/
3
- export default [
3
+ export const chromeDesktopOptions = [
4
4
  '--disable-background-networking',
5
5
  '--no-default-browser-check',
6
6
  '--no-first-run',
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Default trace categories for the Chrome trace log.
3
3
  */
4
- export default [
4
+ export const traceCategories = [
5
5
  '-*',
6
6
  'disabled-by-default-lighthouse',
7
7
  'v8',
@@ -119,9 +119,7 @@ function cleanTrace(trace, url) {
119
119
  // and using TS of first found TracingStartedIn* event
120
120
 
121
121
  // With Chrome 58 we got undefined events on Travis (I cant't reproduce it on my local)
122
- if (mostActiveFrame !== undefined) {
123
- traceEvents.unshift(makeMockEvent(mostActiveFrame, ts));
124
- } else {
122
+ if (mostActiveFrame === undefined) {
125
123
  // sometimes it seems we are missing inserting the 'TracingStartedInPage
126
124
  // let log and find out more
127
125
  log.error(
@@ -130,6 +128,8 @@ function cleanTrace(trace, url) {
130
128
  traceEvents.length,
131
129
  threads
132
130
  );
131
+ } else {
132
+ traceEvents.unshift(makeMockEvent(mostActiveFrame, ts));
133
133
  }
134
134
 
135
135
  // Verify that we got a navigationStart event for that frame. In Chrome 76 we started to get
@@ -4,7 +4,7 @@ import get from 'lodash.get';
4
4
  import { logging } from 'selenium-webdriver';
5
5
  import { ServiceBuilder, Options } from 'selenium-webdriver/chrome.js';
6
6
  import { pac, manual } from 'selenium-webdriver/proxy.js';
7
- import setupChromiumOptions from './setupChromiumOptions.js';
7
+ import { setupChromiumOptions } from './setupChromiumOptions.js';
8
8
 
9
9
  /**
10
10
  * Configure a WebDriver builder based on the specified options.