browsertime 17.5.0-beta3 → 17.5.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.
package/CHANGELOG.md CHANGED
@@ -1,11 +1,14 @@
1
1
  # Browsertime changelog (we do [semantic versioning](https://semver.org))
2
2
 
3
- ## 17.5.0 - UNRELEASED
3
+ ## 17.5.0 - 2022-04-04
4
4
 
5
5
  ### Added
6
- * There's a new better way to get the HAR from [Firefox using WebDriver BiDi network events](https://github.com/firefox-devtools/bidi-har-export). Thank you [Julian Descottes](https://github.com/juliandescottes) and others at Mozilla that made this happen! With the new version we hope to see less overhead getting the HAR + it works on Firefox on Android [#1918](https://github.com/sitespeedio/browsertime/pull/1918).
6
+ * There's a new better way to get the HAR from [Firefox using WebDriver BiDi network events](https://github.com/firefox-devtools/bidi-har-export). Thank you [Julian Descottes](https://github.com/juliandescottes) and others at Mozilla that made this happen! With the new version we hope to see less overhead getting the HAR + it works on Firefox on Android [#1918](https://github.com/sitespeedio/browsertime/pull/1918). You can turn it on with `--firefox.bidihar`.
7
+ * Updated to Geckodriver 0.33 [#1928](https://github.com/sitespeedio/browsertime/pull/1928).
8
+
7
9
  ### Fixed
8
10
  * Fixed the interaction to next paint error message that started to appear in latest Chrome [#1924](https://github.com/sitespeedio/browsertime/pull/1924).
11
+ * Safer check for getting last meaningful paint [#1927](https://github.com/sitespeedio/browsertime/pull/1927)
9
12
 
10
13
  ## 17.4.0 - 2022-03-29
11
14
  ### Added
@@ -86,7 +86,11 @@
86
86
  ) {
87
87
  // If the interaction already exists, update it. Otherwise create one.
88
88
  if (existingInteraction) {
89
- existingInteraction.entries.push(entry);
89
+ existingInteraction.entries.push(
90
+ { id: entry.interactionId,
91
+ latency: entry.duration,
92
+ name: entry.name
93
+ });
90
94
  existingInteraction.latency = Math.max(
91
95
  existingInteraction.latency,
92
96
  entry.duration
@@ -95,7 +99,13 @@
95
99
  const interaction = {
96
100
  id: entry.interactionId,
97
101
  latency: entry.duration,
98
- name: entry.name
102
+ entries: [
103
+ {
104
+ id: entry.interactionId,
105
+ latency: entry.duration,
106
+ name: entry.name
107
+ }
108
+ ]
99
109
  };
100
110
  longestInteractionMap[interaction.id] = interaction;
101
111
  longestInteractionList.push(interaction);
@@ -1287,12 +1287,13 @@ def calculate_visual_metrics(
1287
1287
  )
1288
1288
  # hero_timings.append({'name': 'FirstPaintedHero',
1289
1289
  # 'value': hero_timings_sorted[0]['value']})
1290
- hero_timings.append(
1291
- {
1292
- "name": "LastMeaningfulPaint",
1293
- "value": hero_timings_sorted[-1]["value"],
1294
- }
1295
- )
1290
+ if (len(hero_timings_sorted) > 0):
1291
+ hero_timings.append(
1292
+ {
1293
+ "name": "LastMeaningfulPaint",
1294
+ "value": hero_timings_sorted[-1]["value"],
1295
+ }
1296
+ )
1296
1297
  hero_data["timings"] = hero_timings
1297
1298
  metrics += hero_timings
1298
1299
 
@@ -0,0 +1,66 @@
1
+ import intel from 'intel';
2
+ const log = intel.getLogger('browsertime.firefox');
3
+
4
+ // Get the HAR from Firefox
5
+ // Using https://github.com/firefox-devtools/har-export-trigger
6
+ export async function getHAR(runner, includeResponseBodies) {
7
+ const script = `
8
+ const callback = arguments[arguments.length - 1];
9
+ async function triggerExport() {
10
+ try {
11
+ const result = await HAR.triggerExport();
12
+ if (result.pages.length > 0) {
13
+ result.pages[0].title = document.URL;
14
+ return callback({'har': {log: result}});
15
+ } else {
16
+ return callback({'error': 'The HAR export trigger returned an empty HAR' + JSON.stringify(result)});
17
+ }
18
+ }
19
+ catch(e) {
20
+ // Sometimes the HAR trigger is really slow so then HAR is not defined.
21
+ // we catch that with one extra delay
22
+ const delay = ms => new Promise(res => setTimeout(res, ms));
23
+ await delay(10000);
24
+ try {
25
+ const result = await HAR.triggerExport();
26
+ result.pages[0].title = document.URL;
27
+ return callback({'har': {log: result}});
28
+ } catch(e) {
29
+ return callback({'error': e.toString()});
30
+ }
31
+ }
32
+ };
33
+ return triggerExport();
34
+ `;
35
+
36
+ log.info('Waiting on har-export-trigger to collect the HAR');
37
+ try {
38
+ const harResult = await runner.runAsyncScript(script, 'GET_HAR_SCRIPT');
39
+ if (harResult.har) {
40
+ // The HAR from Firefox always includes content and that can make the HAR file
41
+ // really big, so we have an option to remove it.
42
+ if (
43
+ includeResponseBodies === 'none' ||
44
+ includeResponseBodies === 'html'
45
+ ) {
46
+ for (let entry of harResult.har.log.entries) {
47
+ if (includeResponseBodies === 'none') {
48
+ delete entry.response.content.text;
49
+ } else if (
50
+ entry.response.content.mimeType &&
51
+ !entry.response.content.mimeType.includes('text/html')
52
+ ) {
53
+ delete entry.response.content.text;
54
+ }
55
+ }
56
+ }
57
+ return harResult.har;
58
+ } else {
59
+ log.error(
60
+ 'Got an error from HAR Export Trigger ' + JSON.stringify(harResult)
61
+ );
62
+ }
63
+ } catch (error) {
64
+ log.error('Could not get the HAR from Firefox', error);
65
+ }
66
+ }
@@ -176,7 +176,31 @@ export async function configureBuilder(builder, baseDir, options) {
176
176
  ffOptions.addArguments('-no-remote');
177
177
 
178
178
  // Enable bidi for HAR support
179
- ffOptions.enableBidi();
179
+ if (firefoxConfig.bidihar) {
180
+ ffOptions.enableBidi();
181
+ } else {
182
+ if (!options.skipHar) {
183
+ if (isAndroidConfigured(options)) {
184
+ log.info('Skip install HAR trigger on Android');
185
+ } else {
186
+ // Hack for opening the toolbar
187
+ // In Firefox 61 we need to have devtools open but do not need to choose netmonitor
188
+ // ffOptions.setPreference('devtools.toolbox.selectedTool', 'netmonitor');
189
+ if (!options.debug) {
190
+ ffOptions.setPreference('devtools.toolbox.footer.height', 0);
191
+ ffOptions.addArguments('-devtools');
192
+ }
193
+
194
+ ffOptions.addExtensions(
195
+ resolve(
196
+ moduleRootPath,
197
+ 'vendor',
198
+ 'har_export_trigger-0.6.1-an+fx.xpi'
199
+ )
200
+ );
201
+ }
202
+ }
203
+ }
180
204
 
181
205
  if (firefoxConfig.args) {
182
206
  ffOptions.addArguments(firefoxConfig.args);
@@ -12,6 +12,7 @@ import { findFiles } from '../../support/fileUtil.js';
12
12
  import { GeckoProfiler } from '../geckoProfiler.js';
13
13
  import { MemoryReport } from '../memoryReport.js';
14
14
  import { PerfStats } from '../perfStats.js';
15
+ import { getHAR } from '../getHAR.js';
15
16
 
16
17
  const log = intel.getLogger('browsertime.firefox');
17
18
  const rename = promisify(_rename);
@@ -50,11 +51,13 @@ export class Firefox {
50
51
  * configure what you need.
51
52
  */
52
53
  async afterBrowserStart(runner) {
53
- const windowId = await runner.getDriver().getWindowHandle();
54
- this.har = new adapters.SeleniumBiDiHarRecorder({
55
- browsingContextIds: [windowId],
56
- driver: runner.getDriver()
57
- });
54
+ if (this.firefoxConfig.bidihar) {
55
+ const windowId = await runner.getDriver().getWindowHandle();
56
+ this.har = new adapters.SeleniumBiDiHarRecorder({
57
+ browsingContextIds: [windowId],
58
+ driver: runner.getDriver()
59
+ });
60
+ }
58
61
  }
59
62
 
60
63
  /**
@@ -88,7 +91,7 @@ export class Firefox {
88
91
  });
89
92
  `);
90
93
 
91
- if (!this.skipHar) {
94
+ if (!this.skipHar && this.firefoxConfig.bidihar) {
92
95
  await this.har.startRecording();
93
96
  }
94
97
 
@@ -177,11 +180,19 @@ export class Firefox {
177
180
  }
178
181
  result.cpu = powerusage;
179
182
 
180
- if (this.skipHar) {
183
+ if (
184
+ this.skipHar ||
185
+ (isAndroidConfigured(this.options) && !this.firefoxConfig.bidihar)
186
+ ) {
187
+ if (result.alias && !this.aliasAndUrl[result.alias]) {
188
+ this.aliasAndUrl[result.alias] = result.url;
189
+ }
181
190
  return result;
182
191
  } else {
183
192
  // const harExport = await this.har.stopRecording();
184
- const har = await this.har.stopRecording();
193
+ const har = this.firefoxConfig.bidihar
194
+ ? await this.har.stopRecording()
195
+ : await getHAR(runner, this.includeResponseBodies);
185
196
  if (har.log.pages.length > 0) {
186
197
  // Hack to add the URL from a SPA
187
198
  if (result.alias && !this.aliasAndUrl[result.alias]) {
@@ -438,6 +438,12 @@ export function parseCommandLine() {
438
438
  type: 'boolean',
439
439
  group: 'firefox'
440
440
  })
441
+ .option('firefox.bidihar', {
442
+ describe: 'Use the new bidi HAR generator',
443
+ default: false,
444
+ type: 'boolean',
445
+ group: 'firefox'
446
+ })
441
447
  .option('firefox.windowRecorder', {
442
448
  describe:
443
449
  'Use the internal compositor-based Firefox window recorder to emit PNG files for each ' +
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "browsertime",
3
3
  "description": "Get performance metrics from your web page using Browsertime.",
4
- "version": "17.5.0-beta3",
4
+ "version": "17.5.0",
5
5
  "bin": "./bin/browsertime.js",
6
6
  "type": "module",
7
7
  "dependencies": {
@@ -9,7 +9,7 @@
9
9
  "@devicefarmer/adbkit": "2.11.3",
10
10
  "@sitespeed.io/chromedriver": "111.0.5563-64",
11
11
  "@sitespeed.io/edgedriver": "111.0.1661-41",
12
- "@sitespeed.io/geckodriver": "0.32.2",
12
+ "@sitespeed.io/geckodriver": "0.33.0",
13
13
  "@sitespeed.io/throttle": "5.0.0",
14
14
  "@sitespeed.io/tracium": "0.3.3",
15
15
  "ff-test-bidi-har-export": "0.0.6",