browsertime 16.6.0 → 16.8.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.
@@ -320,6 +320,10 @@ class Chromium {
320
320
  result.browserScripts.pageinfo.cumulativeLayoutShift;
321
321
  }
322
322
  if (result.browserScripts.timings) {
323
+ if (result.browserScripts.timings.ttfb) {
324
+ result.googleWebVitals.ttfb = result.browserScripts.timings.ttfb;
325
+ }
326
+
323
327
  if (result.browserScripts.timings.largestContentfulPaint) {
324
328
  result.googleWebVitals.largestContentfulPaint =
325
329
  result.browserScripts.timings.largestContentfulPaint.renderTime ||
@@ -338,6 +342,11 @@ class Chromium {
338
342
  : 0;
339
343
  }
340
344
 
345
+ if (result.browserScripts.timings.interactionToNextPaint) {
346
+ result.googleWebVitals.interactionToNextPaint =
347
+ result.browserScripts.timings.interactionToNextPaint;
348
+ }
349
+
341
350
  // Add LCP to the HAR
342
351
  if (
343
352
  result.browserScripts.timings.largestContentfulPaint &&
@@ -99,6 +99,10 @@ module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
99
99
  }
100
100
  }
101
101
 
102
+ if (options.debug) {
103
+ seleniumOptions.addArguments('--auto-open-devtools-for-tabs');
104
+ }
105
+
102
106
  const perfLogConf = { enableNetwork: true, enablePage: true };
103
107
  seleniumOptions.setPerfLoggingPrefs(perfLogConf);
104
108
 
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ const log = require('intel').getLogger('browsertime.command.debug');
4
+ const delay = ms => new Promise(res => setTimeout(res, ms));
5
+
6
+ class Debug {
7
+ constructor(browser, options) {
8
+ this.browser = browser;
9
+ this.options = options;
10
+ }
11
+
12
+ /**
13
+ * Add a breakpoint to script. The browser will wait at the breakpoint for user input.
14
+ * @returns {Promise} Promise object that is fulfilled when the user move on from the breakpoint.
15
+ */
16
+ async breakpoint(name) {
17
+ if (this.options.debug) {
18
+ const logMessage = `Pausing for breakpoint ${
19
+ name || ''
20
+ }, set browsertime.pause = false; to continue`;
21
+
22
+ await this.browser.runScript(
23
+ `console.log('${logMessage}');`,
24
+ 'CONSOLE_LOG'
25
+ );
26
+ log.info(logMessage);
27
+ let debug = true;
28
+ await this.browser.runScript(
29
+ 'window.browsertime = {}; window.browsertime.pause = true',
30
+ 'PAUSE_SCRIPT'
31
+ );
32
+ while (debug === true) {
33
+ debug = await this.browser.runScript(
34
+ 'return window.browsertime.pause',
35
+ 'GET_PAUSE_STATUS'
36
+ );
37
+ await delay(1000);
38
+ }
39
+ log.info('Exit breakpoint and continue.');
40
+ return this.browser.runScript(
41
+ 'window.browsertime.pause = false',
42
+ 'SET_PAUSE_STATUS'
43
+ );
44
+ }
45
+ }
46
+ }
47
+
48
+ module.exports = Debug;
@@ -22,6 +22,7 @@ const Cache = require('./command/cache.js');
22
22
  const Meta = require('./command/meta.js');
23
23
  const StopWatch = require('./command/stopWatch.js');
24
24
  const Select = require('./command/select.js');
25
+ const Debug = require('./command/debug.js');
25
26
  const AndroidCommand = require('./command/android.js');
26
27
  const ChromeDevToolsProtocol = require('./command/chromeDevToolsProtocol.js');
27
28
  const { addConnectivity, removeConnectivity } = require('../../connectivity');
@@ -148,7 +149,7 @@ class Iteration {
148
149
 
149
150
  const cdp = new ChromeDevToolsProtocol(engineDelegate, options.browser);
150
151
  const android = new Android(options);
151
-
152
+ const debug = new Debug(browser, options);
152
153
  const commands = {
153
154
  click: new Click(browser, this.pageCompleteCheck),
154
155
  scroll: new Scroll(browser, options),
@@ -172,6 +173,7 @@ class Iteration {
172
173
  screenshot: new Screenshot(screenshotManager, browser, index),
173
174
  cdp,
174
175
  android: new AndroidCommand(options),
176
+ debug: debug,
175
177
  mouse: {
176
178
  moveTo: new MouseMove(browser),
177
179
  contextClick: new ContextClick(browser),
@@ -244,7 +246,17 @@ class Iteration {
244
246
  }
245
247
 
246
248
  await engineDelegate.beforeBrowserStop(browser, index, result);
247
- await browser.stop();
249
+
250
+ // if we are in debig mode we wait on a continue command
251
+ if (options.debug) {
252
+ await debug.breakpoint('End-of-iteration');
253
+ }
254
+
255
+ if (options.browser === 'firefox' && options.debug) {
256
+ log.info('Firefox is kept open in debug mode');
257
+ } else {
258
+ await browser.stop();
259
+ }
248
260
  // Give the browsers some time to stop
249
261
  await delay(2000);
250
262
  await engineDelegate.afterBrowserStopped();
@@ -329,7 +341,11 @@ class Iteration {
329
341
  if (options.connectivity.variance) {
330
342
  await removeConnectivity(options);
331
343
  }
332
- await browser.stop();
344
+ if (options.browser === 'firefox' && options.debug) {
345
+ log.info('Firefox is kept open in debug mode');
346
+ } else {
347
+ await browser.stop();
348
+ }
333
349
  } catch (e) {
334
350
  // Most cases the browser been stopped already
335
351
  }
@@ -103,6 +103,12 @@ module.exports.configureBuilder = function (builder, baseDir, options) {
103
103
  });
104
104
  }
105
105
 
106
+ if (options.debug) {
107
+ ffOptions.addArguments('--devtools');
108
+ // Mozilla use detach to make sure you can inspect the browser
109
+ ffOptions.setPreference('detach', true);
110
+ }
111
+
106
112
  if (!options.skipHar) {
107
113
  if (options.android) {
108
114
  log.info('Skip install HAR trigger on Android');
@@ -110,8 +116,10 @@ module.exports.configureBuilder = function (builder, baseDir, options) {
110
116
  // Hack for opening the toolbar
111
117
  // In Firefox 61 we need to have devtools open but do not need to choose netmonitor
112
118
  // ffOptions.setPreference('devtools.toolbox.selectedTool', 'netmonitor');
113
- ffOptions.setPreference('devtools.toolbox.footer.height', 0);
114
- ffOptions.addArguments('-devtools');
119
+ if (!options.debug) {
120
+ ffOptions.setPreference('devtools.toolbox.footer.height', 0);
121
+ ffOptions.addArguments('-devtools');
122
+ }
115
123
 
116
124
  ffOptions.addExtensions(
117
125
  path.resolve(
@@ -104,19 +104,6 @@ class Firefox {
104
104
  */
105
105
  async afterPageCompleteCheck(runner, index, url, alias) {
106
106
  const result = { url, alias };
107
- if (this.firefoxConfig.collectMozLog) {
108
- const files = await fileUtil.findFiles(this.baseDir, 'moz_log.txt');
109
- for (const file of files) {
110
- await rename(
111
- `${this.baseDir}/${file}`,
112
- path.join(
113
- this.baseDir,
114
- pathToFolder(result.url, this.options),
115
- `${file}-${index}.txt`
116
- )
117
- );
118
- }
119
- }
120
107
 
121
108
  if (this.android && this.options.androidPower) {
122
109
  result.power = await this.android.measurePowerUsage(
@@ -192,6 +179,20 @@ class Firefox {
192
179
 
193
180
  async postWork(index, results) {
194
181
  for (let i = 0; i < results.length; i++) {
182
+ if (this.firefoxConfig.collectMozLog) {
183
+ const files = await fileUtil.findFiles(this.baseDir, 'moz_log.txt');
184
+ for (const file of files) {
185
+ await rename(
186
+ `${this.baseDir}/${file}`,
187
+ path.join(
188
+ this.baseDir,
189
+ pathToFolder(results[i].url, this.options),
190
+ `${file}-${index}.txt`
191
+ )
192
+ );
193
+ }
194
+ }
195
+
195
196
  if (this.firefoxConfig.geckoProfiler && this.options.visualMetrics) {
196
197
  const profileFilename = `geckoProfile-${index}.json.gz`;
197
198
  const profileSubdir = pathToFolder(results[i].url, this.options);
@@ -75,6 +75,18 @@ function validateInput(argv) {
75
75
  return 'You need to specify the --safari.deviceUDID when you run the simulator.';
76
76
  }
77
77
 
78
+ if (argv.debug && argv.browser === 'safari') {
79
+ return 'Debug mode do not work in Safari. Please try with Firefox/Chrome or Edge';
80
+ }
81
+
82
+ if (argv.debug && argv.android) {
83
+ return 'Debug mode do not work on Android. Please run debug mode on Desktop.';
84
+ }
85
+
86
+ if (argv.debug && argv.docker) {
87
+ return 'There is no benefit running debug mode inside a Docker container.';
88
+ }
89
+
78
90
  if (argv.tcpdump) {
79
91
  if (!hasbin.all.sync(['tcpdump'])) {
80
92
  return 'You need to have tcpdump in your path to be able to record a tcpdump.';
@@ -1159,6 +1171,12 @@ module.exports.parseCommandLine = function parseCommandLine() {
1159
1171
  describe:
1160
1172
  'The wait time before you start the real testing after your pre-cache request.'
1161
1173
  })
1174
+ .option('debug', {
1175
+ type: 'boolean',
1176
+ default: false,
1177
+ describe: 'Run Browsertime in debug mode.',
1178
+ group: 'debug'
1179
+ })
1162
1180
 
1163
1181
  .count('verbose')
1164
1182
  .config(config)
@@ -1253,6 +1271,13 @@ module.exports.parseCommandLine = function parseCommandLine() {
1253
1271
  set(argv, 'visualMetrics', get(argv, 'visualMetrics', true));
1254
1272
  }
1255
1273
 
1274
+ // Set the timeouts to a maximum while debugging
1275
+ if (argv.debug) {
1276
+ set(argv, 'timeouts.pageload', 2147483647);
1277
+ set(argv, 'timeouts.script', 2147483647);
1278
+ set(argv, 'timeouts.pageCompleteCheck', 2147483647);
1279
+ }
1280
+
1256
1281
  return {
1257
1282
  urls: argv._,
1258
1283
  options: argv
@@ -91,6 +91,10 @@ function addExtrasToHAR(
91
91
  harPageTimings._firstPaint = timings.firstPaint;
92
92
  }
93
93
 
94
+ if (cpu && cpu.longTasks && cpu.longTasks.lastLongTask) {
95
+ harPageTimings._lastCPULongTask = cpu.longTasks.lastLongTask;
96
+ }
97
+
94
98
  if (timings && timings.largestContentfulPaint) {
95
99
  harPageTimings._largestContentfulPaint =
96
100
  timings.largestContentfulPaint.renderTime;
@@ -81,10 +81,6 @@ module.exports = {
81
81
  scriptArgs.push('--perceptual');
82
82
  }
83
83
 
84
- if (options.visualMetricsNotification) {
85
- scriptArgs.push('--notification');
86
- }
87
-
88
84
  if (options.visualMetricsContentful) {
89
85
  scriptArgs.push('--contentful');
90
86
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "description": "Browsertime",
3
- "version": "16.6.0",
3
+ "version": "16.8.1",
4
4
  "bin": "./bin/browsertime.js",
5
5
  "dependencies": {
6
6
  "@cypress/xvfb": "1.2.4",
7
7
  "@devicefarmer/adbkit": "2.11.3",
8
- "@sitespeed.io/chromedriver": "101.0.4951-15",
8
+ "@sitespeed.io/chromedriver": "102.0.5005-27",
9
9
  "@sitespeed.io/edgedriver": "101.0.1210-32",
10
10
  "@sitespeed.io/geckodriver": "0.31.0",
11
11
  "@sitespeed.io/throttle": "3.1.1",
@@ -26,7 +26,7 @@
26
26
  "lodash.merge": "4.6.2",
27
27
  "lodash.pick": "4.4.0",
28
28
  "lodash.set": "4.3.2",
29
- "selenium-webdriver": "4.1.2",
29
+ "selenium-webdriver": "4.2.0",
30
30
  "yargs": "17.4.1"
31
31
  },
32
32
  "optionalDependencies": {