browsertime 17.3.0 → 17.5.0-beta1
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 +7 -0
- package/lib/chrome/settings/chromeDesktopOptions.js +18 -16
- package/lib/chrome/webdriver/setupChromiumOptions.js +15 -0
- package/lib/core/engine/iteration.js +1 -1
- package/lib/firefox/webdriver/builder.js +3 -18
- package/lib/firefox/webdriver/firefox.js +16 -4
- package/lib/support/util.js +12 -0
- package/package.json +2 -1
- package/lib/firefox/getHAR.js +0 -66
- package/vendor/har_export_trigger-0.6.1-an+fx.xpi +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Browsertime changelog (we do [semantic versioning](https://semver.org))
|
|
2
2
|
|
|
3
|
+
## 17.4.0 - 2022-03-29
|
|
4
|
+
### Added
|
|
5
|
+
* Log the CPU benchmark metric to the console. This is useful (at least for me) when debugging instances with a lot of instability. [#1920](https://github.com/sitespeedio/browsertime/pull/1920).
|
|
6
|
+
* In Chrome 111 some metrics become more instable when running on host with limited CPU. This change also exists in 112 beta. However we where missing out on a couple of command line magic to disable features in Chrome, this fixes that [#1921](https://github.com/sitespeedio/browsertime/pull/1921).
|
|
7
|
+
|
|
3
8
|
## 17.3.0 - 2022-03-26
|
|
4
9
|
|
|
5
10
|
### Fixed
|
|
@@ -7,6 +12,8 @@
|
|
|
7
12
|
|
|
8
13
|
### Added
|
|
9
14
|
* On Linux you can use taskset to assing FFMPEG to specific CPUs using `--videoParams.taskset "0,5,7,9-11" `. It will start FFMPEG with `taskset -c <CPUS>` to pin FFMPG to specific CPU(s). Specify a numerical list of processors. The list may contain multiple items, separated by comma, and ranges. For example, "0,5,7,9-11". Use it together with isolcpus. Added in [#1917](https://github.com/sitespeedio/browsertime/pull/1917).
|
|
15
|
+
|
|
16
|
+
* If you use a rooted Samsung A51 you can now choose the CPU speed (min/middle/max) using `--android.pinCPUSpeed min|middle|max` [#1915](https://github.com/sitespeedio/browsertime/pull/1915).
|
|
10
17
|
## 17.2.1 - 2022-03-16
|
|
11
18
|
### Fixed
|
|
12
19
|
* Bumped Geckodriver to 0.32.2 and Edgedriver to 111.
|
|
@@ -1,26 +1,28 @@
|
|
|
1
|
-
// See https://github.com/GoogleChrome/chrome-launcher/blob/
|
|
1
|
+
// See https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md
|
|
2
2
|
// https://peter.sh/experiments/chromium-command-line-switches/
|
|
3
3
|
export const chromeDesktopOptions = [
|
|
4
|
-
'--disable-background-networking',
|
|
5
|
-
'--no-default-browser-check',
|
|
6
|
-
'--no-first-run',
|
|
7
|
-
'--new-window',
|
|
8
4
|
'--allow-running-insecure-content',
|
|
5
|
+
'--disable-background-networking',
|
|
6
|
+
'--disable-background-timer-throttling',
|
|
7
|
+
'--disable-backgrounding-occluded-windows',
|
|
8
|
+
'--disable-breakpad',
|
|
9
9
|
'--disable-client-side-phishing-detection',
|
|
10
10
|
'--disable-component-update',
|
|
11
11
|
'--disable-default-apps',
|
|
12
|
-
'--disable-
|
|
12
|
+
'--disable-dev-shm-usage',
|
|
13
13
|
'--disable-domain-reliability',
|
|
14
|
-
'--disable-
|
|
15
|
-
'--load-media-router-component-extension=0',
|
|
16
|
-
'--mute-audio',
|
|
14
|
+
'--disable-fetching-hints-at-navigation-start',
|
|
17
15
|
'--disable-hang-monitor',
|
|
16
|
+
'--disable-ipc-flooding-protection',
|
|
17
|
+
'--disable-prompt-on-repost',
|
|
18
|
+
'--disable-renderer-backgrounding',
|
|
19
|
+
'--disable-site-isolation-trials',
|
|
20
|
+
'--disable-sync',
|
|
21
|
+
'--metrics-recording-only',
|
|
22
|
+
'--mute-audio',
|
|
23
|
+
'--new-window',
|
|
24
|
+
'--no-default-browser-check',
|
|
25
|
+
'--no-first-run',
|
|
18
26
|
'--password-store=basic',
|
|
19
|
-
'--
|
|
20
|
-
'--dont-require-litepage-redirect-infobar',
|
|
21
|
-
'--override-https-image-compression-infobar',
|
|
22
|
-
'--disable-fetching-hints-at-navigation-start',
|
|
23
|
-
'--disable-dev-shm-usage',
|
|
24
|
-
'--disable-back-forward-cache',
|
|
25
|
-
'--disable-site-isolation-trials'
|
|
27
|
+
'--use-mock-keychain'
|
|
26
28
|
];
|
|
@@ -19,6 +19,17 @@ const CHROME_AMD_EDGE_INTERNAL_PHONE_HOME = [
|
|
|
19
19
|
'"MAP optimizationguide-pa.googleapis.com 127.0.0.1"'
|
|
20
20
|
];
|
|
21
21
|
|
|
22
|
+
const CHROME_FEATURES_THAT_WE_DISABLES = [
|
|
23
|
+
'AutofillServerCommunication',
|
|
24
|
+
'CalculateNativeWinOcclusion',
|
|
25
|
+
'HeavyAdPrivacyMitigations',
|
|
26
|
+
'InterestFeedContentSuggestions',
|
|
27
|
+
'MediaRouter',
|
|
28
|
+
'OfflinePagesPrefetching',
|
|
29
|
+
'OptimizationHints',
|
|
30
|
+
'Translate'
|
|
31
|
+
];
|
|
32
|
+
|
|
22
33
|
export function setupChromiumOptions(
|
|
23
34
|
seleniumOptions,
|
|
24
35
|
browserOptions,
|
|
@@ -49,6 +60,10 @@ export function setupChromiumOptions(
|
|
|
49
60
|
seleniumOptions.addArguments('--disable-gpu');
|
|
50
61
|
}
|
|
51
62
|
|
|
63
|
+
seleniumOptions.addArguments(
|
|
64
|
+
'--disable-features=' + CHROME_FEATURES_THAT_WE_DISABLES.join(',')
|
|
65
|
+
);
|
|
66
|
+
|
|
52
67
|
const viewPort = getViewPort(options);
|
|
53
68
|
// If viewport is defined (only on desktop) then set start args
|
|
54
69
|
if (viewPort) {
|
|
@@ -112,7 +112,7 @@ export class Iteration {
|
|
|
112
112
|
|
|
113
113
|
await engineDelegate.beforeBrowserStart();
|
|
114
114
|
await browser.start();
|
|
115
|
-
await engineDelegate.afterBrowserStart();
|
|
115
|
+
await engineDelegate.afterBrowserStart(browser);
|
|
116
116
|
|
|
117
117
|
// The data we push to all selenium scripts
|
|
118
118
|
const context = {
|
|
@@ -116,24 +116,6 @@ export async function configureBuilder(builder, baseDir, options) {
|
|
|
116
116
|
ffOptions.setPreference('detach', true);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
if (!options.skipHar) {
|
|
120
|
-
if (isAndroidConfigured(options)) {
|
|
121
|
-
log.info('Skip install HAR trigger on Android');
|
|
122
|
-
} else {
|
|
123
|
-
// Hack for opening the toolbar
|
|
124
|
-
// In Firefox 61 we need to have devtools open but do not need to choose netmonitor
|
|
125
|
-
// ffOptions.setPreference('devtools.toolbox.selectedTool', 'netmonitor');
|
|
126
|
-
if (!options.debug) {
|
|
127
|
-
ffOptions.setPreference('devtools.toolbox.footer.height', 0);
|
|
128
|
-
ffOptions.addArguments('-devtools');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
ffOptions.addExtensions(
|
|
132
|
-
resolve(moduleRootPath, 'vendor', 'har_export_trigger-0.6.1-an+fx.xpi')
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
119
|
// Browsertime own extension, only load it when we need it
|
|
138
120
|
// We should be able to only install it only when needed, but that could break scripting
|
|
139
121
|
|
|
@@ -193,6 +175,9 @@ export async function configureBuilder(builder, baseDir, options) {
|
|
|
193
175
|
|
|
194
176
|
ffOptions.addArguments('-no-remote');
|
|
195
177
|
|
|
178
|
+
// Enable bidi for HAR support
|
|
179
|
+
ffOptions.enableBidi();
|
|
180
|
+
|
|
196
181
|
if (firefoxConfig.args) {
|
|
197
182
|
ffOptions.addArguments(firefoxConfig.args);
|
|
198
183
|
}
|
|
@@ -3,15 +3,16 @@ import { promisify } from 'node:util';
|
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import intel from 'intel';
|
|
5
5
|
import get from 'lodash.get';
|
|
6
|
+
import { adapters } from 'ff-test-bidi-har-export';
|
|
6
7
|
import { getEmptyHAR, mergeHars } from '../../support/har/index.js';
|
|
7
8
|
import { pathToFolder } from '../../support/pathToFolder.js';
|
|
8
9
|
import { isAndroidConfigured, Android } from '../../android/index.js';
|
|
9
10
|
import { adjustVisualProgressTimestamps } from '../../support/util.js';
|
|
10
11
|
import { findFiles } from '../../support/fileUtil.js';
|
|
11
|
-
import { getHAR } from '../getHAR.js';
|
|
12
12
|
import { GeckoProfiler } from '../geckoProfiler.js';
|
|
13
13
|
import { MemoryReport } from '../memoryReport.js';
|
|
14
14
|
import { PerfStats } from '../perfStats.js';
|
|
15
|
+
|
|
15
16
|
const log = intel.getLogger('browsertime.firefox');
|
|
16
17
|
const rename = promisify(_rename);
|
|
17
18
|
export class Firefox {
|
|
@@ -48,7 +49,13 @@ export class Firefox {
|
|
|
48
49
|
* The browser is up and running, now its time to start to
|
|
49
50
|
* configure what you need.
|
|
50
51
|
*/
|
|
51
|
-
async afterBrowserStart() {
|
|
52
|
+
async afterBrowserStart(runner) {
|
|
53
|
+
const windowId = await runner.getDriver().getWindowHandle();
|
|
54
|
+
this.har = new adapters.SeleniumBiDiHarRecorder({
|
|
55
|
+
browsingContextIds: [windowId],
|
|
56
|
+
driver: runner.getDriver()
|
|
57
|
+
});
|
|
58
|
+
}
|
|
52
59
|
|
|
53
60
|
/**
|
|
54
61
|
* Before the first iteration of your tests start.
|
|
@@ -81,6 +88,10 @@ export class Firefox {
|
|
|
81
88
|
});
|
|
82
89
|
`);
|
|
83
90
|
|
|
91
|
+
if (!this.skipHar) {
|
|
92
|
+
await this.har.startRecording();
|
|
93
|
+
}
|
|
94
|
+
|
|
84
95
|
if (isAndroidConfigured(this.options) && this.options.androidPower) {
|
|
85
96
|
await this.android.resetPowerUsage();
|
|
86
97
|
}
|
|
@@ -166,10 +177,11 @@ export class Firefox {
|
|
|
166
177
|
}
|
|
167
178
|
result.cpu = powerusage;
|
|
168
179
|
|
|
169
|
-
if (this.skipHar
|
|
180
|
+
if (this.skipHar) {
|
|
170
181
|
return result;
|
|
171
182
|
} else {
|
|
172
|
-
const
|
|
183
|
+
// const harExport = await this.har.stopRecording();
|
|
184
|
+
const har = await this.har.stopRecording();
|
|
173
185
|
if (har.log.pages.length > 0) {
|
|
174
186
|
// Hack to add the URL from a SPA
|
|
175
187
|
if (result.alias && !this.aliasAndUrl[result.alias]) {
|
package/lib/support/util.js
CHANGED
|
@@ -38,6 +38,7 @@ export function logResultLogLine(results) {
|
|
|
38
38
|
fcp = '',
|
|
39
39
|
cls = '',
|
|
40
40
|
tbt = '',
|
|
41
|
+
cpuBenchmark = '',
|
|
41
42
|
nRuns = result.browserScripts.length,
|
|
42
43
|
m = nRuns > 1;
|
|
43
44
|
if (results.har && results.har.log.pages[index]) {
|
|
@@ -59,6 +60,16 @@ export function logResultLogLine(results) {
|
|
|
59
60
|
: totalSize + ' bytes';
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
if (result.statistics.browser && result.statistics.browser.cpuBenchmark) {
|
|
64
|
+
cpuBenchmark = formatMetric(
|
|
65
|
+
'CPUBenchmark',
|
|
66
|
+
result.statistics.browser.cpuBenchmark,
|
|
67
|
+
true,
|
|
68
|
+
true,
|
|
69
|
+
m
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
62
73
|
if (result.statistics.timings && result.statistics.timings.pageTimings) {
|
|
63
74
|
let pt = result.statistics.timings.pageTimings,
|
|
64
75
|
t = result.statistics.timings,
|
|
@@ -178,6 +189,7 @@ export function logResultLogLine(results) {
|
|
|
178
189
|
lcp,
|
|
179
190
|
cls,
|
|
180
191
|
tbt,
|
|
192
|
+
cpuBenchmark,
|
|
181
193
|
pageLoad,
|
|
182
194
|
memory,
|
|
183
195
|
speedIndex,
|
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.
|
|
4
|
+
"version": "17.5.0-beta1",
|
|
5
5
|
"bin": "./bin/browsertime.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"dependencies": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"@sitespeed.io/geckodriver": "0.32.2",
|
|
13
13
|
"@sitespeed.io/throttle": "5.0.0",
|
|
14
14
|
"@sitespeed.io/tracium": "0.3.3",
|
|
15
|
+
"ff-test-bidi-har-export": "0.0.5",
|
|
15
16
|
"btoa": "1.2.1",
|
|
16
17
|
"chrome-har": "0.13.1",
|
|
17
18
|
"chrome-remote-interface": "0.32.1",
|
package/lib/firefox/getHAR.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
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
|
-
}
|
|
Binary file
|