browsertime 16.17.0 → 17.0.0-beta.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 (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 +81 -71
  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 +43 -48
  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,6 +1,5 @@
1
- 'use strict';
2
- const { isAndroidConfigured } = require('../../../android');
3
- const getFont = require('./getFont');
1
+ import { isAndroidConfigured } from '../../../android/index.js';
2
+ import getFont from './getFont.js';
4
3
 
5
4
  function isSmallish(options) {
6
5
  return (
@@ -31,26 +30,28 @@ function get(metric, metricName, pos, options) {
31
30
  },30)':x=(w-tw)/2: y=H-${pos}-h/${x}:fontcolor=white:fontsize=h/${fontSize}:box=1:boxcolor=0x000000AA:boxborderw=2:text='${metricName} ${metric}'`;
32
31
  }
33
32
 
34
- module.exports = function (videoMetrics, timingMetrics, options) {
33
+ export default function (videoMetrics, timingMetrics, options) {
35
34
  let text = '';
36
35
  const vm = videoMetrics.visualMetrics;
37
36
  const startPosition = 'h/10';
38
37
  const metricsAndValues = [];
39
38
 
40
39
  if (options.visualMetrics) {
41
- metricsAndValues.push({
42
- name: 'FirstVisualChange',
43
- value: vm.FirstVisualChange
44
- });
45
- metricsAndValues.push({ name: 'SpeedIndex', value: vm.SpeedIndex });
46
- metricsAndValues.push({
47
- name: 'VisualComplete85',
48
- value: vm.VisualComplete85
49
- });
50
- metricsAndValues.push({
51
- name: 'LastVisualChange',
52
- value: vm.LastVisualChange
53
- });
40
+ metricsAndValues.push(
41
+ {
42
+ name: 'FirstVisualChange',
43
+ value: vm.FirstVisualChange
44
+ },
45
+ { name: 'SpeedIndex', value: vm.SpeedIndex },
46
+ {
47
+ name: 'VisualComplete85',
48
+ value: vm.VisualComplete85
49
+ },
50
+ {
51
+ name: 'LastVisualChange',
52
+ value: vm.LastVisualChange
53
+ }
54
+ );
54
55
  }
55
56
 
56
57
  if (vm.LargestContentfulPaint) {
@@ -83,4 +84,4 @@ module.exports = function (videoMetrics, timingMetrics, options) {
83
84
  pos += `-h/${posOffset}`;
84
85
  }
85
86
  return text;
86
- };
87
+ }
@@ -1,19 +1,23 @@
1
- 'use strict';
1
+ import { join } from 'node:path';
2
+ import {
3
+ rename as _rename,
4
+ copyFile as _copyFile,
5
+ unlink as _unlink
6
+ } from 'node:fs';
7
+ import { promisify } from 'node:util';
8
+ import intel from 'intel';
9
+ import get from 'lodash.get';
10
+ import addTextToVideo from './addTextToVideo.js';
11
+ import removeOrange from './removeOrange.js';
12
+ import convert from './convertFps.js';
13
+ import { convert as _convert } from '../../defaults.js';
14
+ import { isAndroidConfigured } from '../../../android/index.js';
15
+ const rename = promisify(_rename);
16
+ const copyFile = promisify(_copyFile);
17
+ const unlink = promisify(_unlink);
18
+ const log = intel.getLogger('browsertime.video');
2
19
 
3
- const log = require('intel').getLogger('browsertime.video');
4
- const addTextToVideo = require('./addTextToVideo');
5
- const removeOrange = require('./removeOrange');
6
- const convert = require('./convertFps');
7
- const path = require('path');
8
- const fs = require('fs');
9
- const get = require('lodash.get');
10
- const { promisify } = require('util');
11
- const rename = promisify(fs.rename);
12
- const copyFile = promisify(fs.copyFile);
13
- const unlink = promisify(fs.unlink);
14
- const defaults = require('../../defaults');
15
-
16
- module.exports = async function (
20
+ export default async function (
17
21
  videoDir,
18
22
  videoPath,
19
23
  index,
@@ -22,10 +26,10 @@ module.exports = async function (
22
26
  options
23
27
  ) {
24
28
  const newStart = videoMetrics.videoRecordingStart / 1000;
25
- let tmpFile = path.join(videoDir, 'tmp.mp4');
29
+ let temporaryFile = join(videoDir, 'tmp.mp4');
26
30
 
27
31
  if (get(options, 'videoParams.keepOriginalVideo', false)) {
28
- const originalFile = path.join(videoDir, index + '-original.mp4');
32
+ const originalFile = join(videoDir, index + '-original.mp4');
29
33
  await copyFile(videoPath, originalFile);
30
34
  }
31
35
 
@@ -34,7 +38,7 @@ module.exports = async function (
34
38
  if (videoMetrics.videoRecordingStart > 0) {
35
39
  await removeOrange(
36
40
  videoPath,
37
- tmpFile,
41
+ temporaryFile,
38
42
  newStart,
39
43
  videoMetrics.visualMetrics,
40
44
  options
@@ -48,36 +52,36 @@ module.exports = async function (
48
52
  videoMetrics
49
53
  );
50
54
  }
51
- tmpFile = videoPath;
55
+ temporaryFile = videoPath;
52
56
  }
53
57
 
54
58
  if (
55
- options.android &&
56
- get(options, 'videoParams.convert', defaults.convert)
59
+ isAndroidConfigured(options) &&
60
+ get(options, 'videoParams.convert', _convert)
57
61
  ) {
58
- const tmpFile2 = path.join(videoDir, 'tmp-60fps.mp4');
59
- await convert(tmpFile, tmpFile2, 60);
60
- await unlink(tmpFile);
61
- await rename(tmpFile2, tmpFile);
62
+ const temporaryFile2 = join(videoDir, 'tmp-60fps.mp4');
63
+ await convert(temporaryFile, temporaryFile2, 60);
64
+ await unlink(temporaryFile);
65
+ await rename(temporaryFile2, temporaryFile);
62
66
  } else if (options.safari && options.safari.useSimulator) {
63
- const tmpFile2 = path.join(videoDir, 'tmp-60fps.mp4');
64
- await convert(tmpFile, tmpFile2, 60);
65
- await unlink(tmpFile);
66
- await rename(tmpFile2, tmpFile);
67
+ const temporaryFile2 = join(videoDir, 'tmp-60fps.mp4');
68
+ await convert(temporaryFile, temporaryFile2, 60);
69
+ await unlink(temporaryFile);
70
+ await rename(temporaryFile2, temporaryFile);
67
71
  }
68
72
 
69
73
  if (options.videoParams.addTimer) {
70
- const tmpFile2 = path.join(videoDir, 'tmp2.mp4');
74
+ const temporaryFile2 = join(videoDir, 'tmp2.mp4');
71
75
  await addTextToVideo(
72
- tmpFile,
73
- tmpFile2,
76
+ temporaryFile,
77
+ temporaryFile2,
74
78
  videoMetrics,
75
79
  timingMetrics,
76
80
  options
77
81
  );
78
- await rename(tmpFile2, videoPath);
79
- await unlink(tmpFile);
82
+ await rename(temporaryFile2, videoPath);
83
+ await unlink(temporaryFile);
80
84
  } else {
81
- await rename(tmpFile, videoPath);
85
+ await rename(temporaryFile, videoPath);
82
86
  }
83
- };
87
+ }
@@ -1,9 +1,8 @@
1
- 'use strict';
1
+ import { execa } from 'execa';
2
+ import intel from 'intel';
3
+ const log = intel.getLogger('browsertime.video');
2
4
 
3
- const execa = require('execa');
4
- const log = require('intel').getLogger('browsertime.video');
5
-
6
- module.exports = async function (
5
+ export default async function (
7
6
  inputFile,
8
7
  outputFile,
9
8
  newStart,
@@ -11,14 +10,14 @@ module.exports = async function (
11
10
  options
12
11
  ) {
13
12
  // Remove the orange frames from the video (and stop the video after last visual change)
14
- const args = ['-nostdin', '-ss', newStart, '-i', inputFile];
13
+ const arguments_ = ['-nostdin', '-ss', newStart, '-i', inputFile];
15
14
  if (options.visualMetrics) {
16
15
  // End the video on last visual change + 1 s
17
16
  const end = newStart + visualMetrics.LastVisualChange / 1000 + 1;
18
- args.push('-to', end);
17
+ arguments_.push('-to', end);
19
18
  }
20
- args.push('-c', 'copy', outputFile);
19
+ arguments_.push('-c', 'copy', outputFile);
21
20
 
22
- log.verbose('Removing orange start with FFMPEG ' + args.join(' '));
23
- return execa('ffmpeg', args);
24
- };
21
+ log.verbose('Removing orange start with FFMPEG ' + arguments_.join(' '));
22
+ return execa('ffmpeg', arguments_);
23
+ }
@@ -1,6 +1,4 @@
1
- 'use strict';
2
-
3
- module.exports = function (metrics) {
1
+ export default function (metrics) {
4
2
  const videoMetrics = {};
5
3
  if (!metrics.VisualReadiness) {
6
4
  metrics.VisualReadiness =
@@ -11,26 +9,32 @@ module.exports = function (metrics) {
11
9
  const eachLine = metrics.VisualProgress.split(',');
12
10
  for (const timeAndPercentage of eachLine) {
13
11
  const [timestamp, percent] = timeAndPercentage.split('=');
14
- if (parseInt(percent, 10) >= 85 && !metrics.VisualComplete85) {
15
- metrics.VisualComplete85 = parseInt(timestamp, 10);
12
+ if (Number.parseInt(percent, 10) >= 85 && !metrics.VisualComplete85) {
13
+ metrics.VisualComplete85 = Number.parseInt(timestamp, 10);
16
14
  }
17
- if (parseInt(percent, 10) >= 95 && !metrics.VisualComplete95) {
18
- metrics.VisualComplete95 = parseInt(timestamp, 10);
15
+ if (Number.parseInt(percent, 10) >= 95 && !metrics.VisualComplete95) {
16
+ metrics.VisualComplete95 = Number.parseInt(timestamp, 10);
19
17
  }
20
- if (parseInt(percent, 10) >= 99 && !metrics.VisualComplete99) {
21
- metrics.VisualComplete99 = parseInt(timestamp, 10);
18
+ if (Number.parseInt(percent, 10) >= 99 && !metrics.VisualComplete99) {
19
+ metrics.VisualComplete99 = Number.parseInt(timestamp, 10);
22
20
  }
23
21
 
24
22
  // Oh noo the painting on the screen goes backward
25
23
  // see https://github.com/sitespeedio/sitespeed.io/issues/2259#issuecomment-456878707
26
- if (metrics.VisualComplete85 && parseInt(percent, 10) < 85) {
24
+ if (metrics.VisualComplete85 && Number.parseInt(percent, 10) < 85) {
27
25
  metrics.VisualComplete85 = undefined;
28
26
  metrics.VisualComplete95 = undefined;
29
27
  metrics.VisualComplete95 = undefined;
30
- } else if (metrics.VisualComplete95 && parseInt(percent, 10) < 95) {
28
+ } else if (
29
+ metrics.VisualComplete95 &&
30
+ Number.parseInt(percent, 10) < 95
31
+ ) {
31
32
  metrics.VisualComplete95 = undefined;
32
33
  metrics.VisualComplete95 = undefined;
33
- } else if (metrics.VisualComplete99 && parseInt(percent, 10) < 99) {
34
+ } else if (
35
+ metrics.VisualComplete99 &&
36
+ Number.parseInt(percent, 10) < 99
37
+ ) {
34
38
  metrics.VisualComplete99 = undefined;
35
39
  }
36
40
  }
@@ -40,4 +44,4 @@ module.exports = function (metrics) {
40
44
  }
41
45
  videoMetrics.visualMetrics = metrics;
42
46
  return videoMetrics;
43
- };
47
+ }
@@ -1,11 +1,10 @@
1
- 'use strict';
1
+ import { join } from 'node:path';
2
+ import intel from 'intel';
3
+ import { run } from './visualMetrics.js';
4
+ import extraMetrics from './extraMetrics.js';
5
+ const log = intel.getLogger('browsertime.video');
2
6
 
3
- const log = require('intel').getLogger('browsertime.video');
4
- const path = require('path');
5
- const visualMetrics = require('./visualMetrics');
6
- const extraMetrics = require('./extraMetrics');
7
-
8
- module.exports = async function (
7
+ export default async function (
9
8
  videoDir,
10
9
  filmstripDir,
11
10
  videoPath,
@@ -26,12 +25,12 @@ module.exports = async function (
26
25
  true
27
26
  );
28
27
  }
29
- const elementsFile = path.join(
28
+ const elementsFile = join(
30
29
  storageManager.directory,
31
30
  index + '-visualElements.json.gz'
32
31
  );
33
32
  try {
34
- const metrics = await visualMetrics.run(
33
+ const metrics = await run(
35
34
  videoPath,
36
35
  filmstripDir,
37
36
  elementsFile,
@@ -43,13 +42,13 @@ module.exports = async function (
43
42
  );
44
43
  log.debug('Collected metrics ' + JSON.stringify(metrics));
45
44
  return extraMetrics(metrics);
46
- } catch (e) {
47
- log.error('Could not run Visual Metrics', e);
48
- throw e;
45
+ } catch (error) {
46
+ log.error('Could not run Visual Metrics', error);
47
+ throw error;
49
48
  } finally {
50
49
  // Remove the file
51
50
  if (options.visualElements && visualElements) {
52
51
  await storageManager.rm(index + '-visualElements.json.gz');
53
52
  }
54
53
  }
55
- };
54
+ }
@@ -1,12 +1,14 @@
1
- 'use strict';
2
-
3
- const execa = require('execa');
4
- const log = require('intel').getLogger('browsertime.video');
5
- const get = require('lodash.get');
6
- const path = require('path');
7
- const { readFile, removeFile, copyFile } = require('../../../support/fileUtil');
8
-
9
- const SCRIPT_PATH = path.join(
1
+ import { fileURLToPath } from 'node:url';
2
+ import { join } from 'node:path';
3
+ import path from 'node:path';
4
+ import { execa } from 'execa';
5
+ import intel from 'intel';
6
+ import get from 'lodash.get';
7
+ import { readFile, removeFile, copyFile } from '../../../support/fileUtil.js';
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ const log = intel.getLogger('browsertime.video');
10
+
11
+ const SCRIPT_PATH = join(
10
12
  __dirname,
11
13
  '..',
12
14
  '..',
@@ -16,7 +18,7 @@ const SCRIPT_PATH = path.join(
16
18
  'visualmetrics.py'
17
19
  );
18
20
 
19
- const PORTABLE_SCRIPT_PATH = path.join(
21
+ const PORTABLE_SCRIPT_PATH = join(
20
22
  __dirname,
21
23
  '..',
22
24
  '..',
@@ -34,133 +36,120 @@ function getScript(options) {
34
36
  return SCRIPT_PATH;
35
37
  }
36
38
 
37
- module.exports = {
38
- async checkDependencies(options) {
39
- return execa(process.env.PYTHON || 'python', [
40
- getScript(options),
41
- '--check'
42
- ]);
43
- },
44
- async run(
39
+ export async function checkDependencies(options) {
40
+ return execa(process.env.PYTHON || 'python', [getScript(options), '--check']);
41
+ }
42
+ export async function run(
43
+ videoPath,
44
+ imageDirPath,
45
+ elementsFile,
46
+ videoDir,
47
+ index,
48
+ pageNumber,
49
+ visitedPageNumber,
50
+ options
51
+ ) {
52
+ const filmstripQuality = get(options, 'videoParams.filmstripQuality', 75);
53
+ const createFilmstrip = get(options, 'videoParams.createFilmstrip', true);
54
+ const fullSizeFilmstrip = get(
55
+ options,
56
+ 'videoParams.filmstripFullSize',
57
+ false
58
+ );
59
+
60
+ const thumbsize = get(options, 'videoParams.thumbsize', 400);
61
+
62
+ const scriptArguments = [
63
+ '--video',
45
64
  videoPath,
46
- imageDirPath,
47
- elementsFile,
48
- videoDir,
49
- index,
50
- pageNumber,
51
- visitedPageNumber,
52
- options
53
- ) {
54
- const filmstripQuality = get(options, 'videoParams.filmstripQuality', 75);
55
- const createFilmstrip = get(options, 'videoParams.createFilmstrip', true);
56
- const fullSizeFilmstrip = get(
57
- options,
58
- 'videoParams.filmstripFullSize',
59
- false
60
- );
61
-
62
- const thumbsize = get(options, 'videoParams.thumbsize', 400);
63
-
64
- const scriptArgs = [
65
- '--video',
66
- videoPath,
67
- '--orange',
68
- '--force',
69
- '--renderignore',
70
- 5,
71
- '--json',
72
- '--viewport',
73
- '--viewportretries',
74
- 60,
75
- '--viewportminheight',
76
- 100,
77
- '--viewportminwidth',
78
- 100
79
- ];
80
-
81
- if (options.visualMetricsPerceptual) {
82
- scriptArgs.push('--perceptual');
83
- }
84
-
85
- if (options.visualMetricsContentful) {
86
- scriptArgs.push('--contentful');
87
- }
65
+ '--orange',
66
+ '--force',
67
+ '--renderignore',
68
+ 5,
69
+ '--json',
70
+ '--viewport',
71
+ '--viewportretries',
72
+ 60,
73
+ '--viewportminheight',
74
+ 100,
75
+ '--viewportminwidth',
76
+ 100
77
+ ];
78
+
79
+ if (options.visualMetricsPerceptual) {
80
+ scriptArguments.push('--perceptual');
81
+ }
88
82
 
89
- // There seems to be a bug with --startwhite that makes VM bail out
90
- // 11:20:14.950 - Calculating image histograms
91
- // 11:20:14.951 - No video frames found in /private/var/folders/27/xpnvcsbs0nlfbb4qq397z3rh0000gn/T/vis-cn_JMf
92
- // 11:20:14.951 - Done calculating histograms
93
- // Since we tuned the borders of the video, I hope it will just work fine
94
- // without. If not, let us create a upstream issue
95
- // If it is the first page and no preURL we can use
96
- // start white, that gives us less variance in metrics in Chrome
97
- /*
98
- if (!options.preURL && visitedPageNumber === 0) {
99
- scriptArgs.push('--startwhite');
100
- }
101
- */
83
+ if (options.visualMetricsContentful) {
84
+ scriptArguments.push('--contentful');
85
+ }
102
86
 
103
- if (options.visualElements) {
104
- scriptArgs.push('--herodata');
105
- scriptArgs.push(elementsFile);
106
- }
87
+ // There seems to be a bug with --startwhite that makes VM bail out
88
+ // 11:20:14.950 - Calculating image histograms
89
+ // 11:20:14.951 - No video frames found in /private/var/folders/27/xpnvcsbs0nlfbb4qq397z3rh0000gn/T/vis-cn_JMf
90
+ // 11:20:14.951 - Done calculating histograms
91
+ // Since we tuned the borders of the video, I hope it will just work fine
92
+ // without. If not, let us create a upstream issue
93
+ // If it is the first page and no preURL we can use
94
+ // start white, that gives us less variance in metrics in Chrome
95
+ /*
96
+ if (!options.preURL && visitedPageNumber === 0) {
97
+ scriptArgs.push('--startwhite');
98
+ }
99
+ */
100
+ if (options.visualElements) {
101
+ scriptArguments.push('--herodata', elementsFile);
102
+ }
107
103
 
108
- if (createFilmstrip) {
109
- scriptArgs.push('-q');
110
- scriptArgs.push(filmstripQuality);
111
- scriptArgs.unshift('--dir', imageDirPath);
112
- if (fullSizeFilmstrip) {
113
- scriptArgs.push('--full');
114
- } else if (thumbsize !== 400) {
115
- scriptArgs.push('--thumbsize');
116
- scriptArgs.push(thumbsize);
117
- }
104
+ if (createFilmstrip) {
105
+ scriptArguments.push('-q', filmstripQuality);
106
+ scriptArguments.unshift('--dir', imageDirPath);
107
+ if (fullSizeFilmstrip) {
108
+ scriptArguments.push('--full');
109
+ } else if (thumbsize !== 400) {
110
+ scriptArguments.push('--thumbsize', thumbsize);
118
111
  }
112
+ }
119
113
 
120
- const visualMetricsLogFile = path.join(
121
- videoDir,
122
- index + '.visualmetrics.log'
123
- );
124
-
125
- scriptArgs.push('--logfile');
126
- scriptArgs.push(visualMetricsLogFile);
127
- if (options.verbose >= 1) {
128
- scriptArgs.push('-vvvv');
129
- } else {
130
- // Full -vvvv is really chatty so keep this level for now.
131
- scriptArgs.push('-vvv');
132
- }
114
+ const visualMetricsLogFile = join(videoDir, index + '.visualmetrics.log');
133
115
 
134
- scriptArgs.unshift(getScript(options));
135
-
136
- log.debug('Running visualmetrics.py ' + scriptArgs.join(' '));
137
- log.info('Get visual metrics from the video');
138
- try {
139
- const result = await execa(process.env.PYTHON || 'python', scriptArgs);
140
- log.debug('visualmetrics.py output:' + result.stdout);
141
- if (options.verbose < 1) {
142
- try {
143
- await removeFile(visualMetricsLogFile);
144
- } catch (e) {
145
- log.error(
146
- 'Could not remove the log file from VisualMetrics, does it exist?: %s',
147
- visualMetricsLogFile
148
- );
149
- }
150
- }
151
- return JSON.parse(result.stdout);
152
- } catch (e) {
153
- log.error('VisualMetrics failed to run', e);
154
- await copyFile(videoPath, videoPath + '.failed.mp4');
116
+ scriptArguments.push('--logfile', visualMetricsLogFile);
117
+ if (options.verbose >= 1) {
118
+ scriptArguments.push('-vvvv');
119
+ } else {
120
+ // Full -vvvv is really chatty so keep this level for now.
121
+ scriptArguments.push('-vvv');
122
+ }
155
123
 
156
- if (options.visualElements) {
157
- await copyFile(elementsFile, elementsFile + '.failed.json');
124
+ scriptArguments.unshift(getScript(options));
125
+
126
+ log.debug('Running visualmetrics.py ' + scriptArguments.join(' '));
127
+ log.info('Get visual metrics from the video');
128
+ try {
129
+ const result = await execa(process.env.PYTHON || 'python', scriptArguments);
130
+ log.debug('visualmetrics.py output:' + result.stdout);
131
+ if (options.verbose < 1) {
132
+ try {
133
+ await removeFile(visualMetricsLogFile);
134
+ } catch {
135
+ log.error(
136
+ 'Could not remove the log file from VisualMetrics, does it exist?: %s',
137
+ visualMetricsLogFile
138
+ );
158
139
  }
140
+ }
141
+ return JSON.parse(result.stdout);
142
+ } catch (error) {
143
+ log.error('VisualMetrics failed to run', error);
144
+ await copyFile(videoPath, videoPath + '.failed.mp4');
159
145
 
160
- // If something goes wrong, dump the visual metrics log to our log
161
- const visualMetricLog = await readFile(visualMetricsLogFile);
162
- log.error('Log from VisualMetrics: %s', visualMetricLog);
163
- throw e;
146
+ if (options.visualElements) {
147
+ await copyFile(elementsFile, elementsFile + '.failed.json');
164
148
  }
149
+
150
+ // If something goes wrong, dump the visual metrics log to our log
151
+ const visualMetricLog = await readFile(visualMetricsLogFile);
152
+ log.error('Log from VisualMetrics: %s', visualMetricLog);
153
+ throw error;
165
154
  }
166
- };
155
+ }
@@ -1,22 +1,17 @@
1
- 'use strict';
2
- const util = require('util');
3
- const fs = require('fs');
4
- const get = require('lodash.get');
5
- const log = require('intel').getLogger('browsertime.video');
6
- const videoDefaults = require('../../defaults');
7
- const { Android } = require('../../../android');
8
- const unlink = util.promisify(fs.unlink);
9
-
1
+ import { promisify } from 'node:util';
2
+ import { unlink as _unlink } from 'node:fs';
3
+ import get from 'lodash.get';
4
+ import intel from 'intel';
5
+ import { framerate } from '../../defaults.js';
6
+ import { Android } from '../../../android/index.js';
7
+ const unlink = promisify(_unlink);
8
+ const log = intel.getLogger('browsertime.video');
10
9
  const delay = ms => new Promise(res => setTimeout(res, ms));
11
10
 
12
- module.exports = class AndroidRecorder {
11
+ export default class AndroidRecorder {
13
12
  constructor(options) {
14
13
  this.waitTime = get(options, 'videoParams.androidVideoWaitTime', 5000);
15
- this.framerate = get(
16
- options,
17
- 'videoParams.framerate',
18
- videoDefaults.framerate
19
- );
14
+ this.framerate = get(options, 'videoParams.framerate', framerate);
20
15
  this.options = options;
21
16
  }
22
17
 
@@ -35,11 +30,11 @@ module.exports = class AndroidRecorder {
35
30
  if (this.options.resultDir) {
36
31
  try {
37
32
  await unlink(destination);
38
- } catch (e) {
33
+ } catch {
39
34
  // Nothing to see here
40
35
  }
41
36
  }
42
37
  await this.android.pullVideo(destination);
43
38
  return this.android.removeVideo();
44
39
  }
45
- };
40
+ }
@@ -1,13 +1,12 @@
1
- 'use strict';
1
+ import { execa } from 'execa';
2
+ import intel from 'intel';
3
+ const log = intel.getLogger('browsertime.video');
2
4
 
3
- const execa = require('execa');
4
- const log = require('intel').getLogger('browsertime.video');
5
-
6
- module.exports = async function convert(src, dest, crf, threads) {
7
- const scriptArgs = [
5
+ export default async function convert(source, destination, crf, threads) {
6
+ const scriptArguments = [
8
7
  '-nostdin',
9
8
  '-i',
10
- src,
9
+ source,
11
10
  '-c:v',
12
11
  'libx264',
13
12
  '-threads',
@@ -18,10 +17,13 @@ module.exports = async function convert(src, dest, crf, threads) {
18
17
  'fast',
19
18
  '-vf',
20
19
  'format=yuv420p',
21
- dest
20
+ destination
22
21
  ];
23
22
 
24
- log.debug('Converting video to viewable format with args %j', scriptArgs);
23
+ log.debug(
24
+ 'Converting video to viewable format with args %j',
25
+ scriptArguments
26
+ );
25
27
 
26
- return execa('ffmpeg', scriptArgs);
27
- };
28
+ return execa('ffmpeg', scriptArguments);
29
+ }