browsertime 21.7.1 → 22.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.
- package/CHANGELOG.md +23 -1
- package/lib/chrome/webdriver/setupChromiumOptions.js +1 -0
- package/lib/core/engine/command/cache.js +3 -21
- package/lib/core/engine/command/measure.js +6 -20
- package/lib/core/engine/commands.js +1 -3
- package/lib/core/engine/iteration.js +0 -3
- package/lib/firefox/webdriver/builder.js +0 -41
- package/lib/firefox/webdriver/firefox.js +4 -11
- package/lib/support/cli.js +2 -13
- package/package.json +5 -5
- package/types/core/engine/command/cache.d.ts +1 -7
- package/types/core/engine/command/cache.d.ts.map +1 -1
- package/types/core/engine/command/measure.d.ts +1 -5
- package/types/core/engine/command/measure.d.ts.map +1 -1
- package/types/core/engine/commands.d.ts +1 -1
- package/types/core/engine/commands.d.ts.map +1 -1
- package/lib/extensionserver/httpServer.js +0 -20
- package/lib/extensionserver/index.js +0 -46
- package/lib/extensionserver/setup.js +0 -39
- package/lib/firefox/getHAR.js +0 -66
- package/vendor/browsertime-0.18.0-an+fx.xpi +0 -0
- package/vendor/browsertime-extension.crx +0 -0
- package/vendor/har_export_trigger-0.6.1-an+fx.xpi +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
# Browsertime changelog (we do [semantic versioning](https://semver.org))
|
|
2
2
|
|
|
3
|
+
## 22.1.0 - 2024-05-20
|
|
4
|
+
### Added
|
|
5
|
+
* Updated to Edge and Edgedriver 125 [#2132](https://github.com/sitespeedio/browsertime/pull/2132).
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
* Updated to Selenium Webdriver 4.21.0 [#2131](https://github.com/sitespeedio/browsertime/pull/2131).
|
|
9
|
+
* Trying to remove new Chrome popup [#2130](https://github.com/sitespeedio/browsertime/pull/2130).
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## 22.0.0 - 2024-05-16
|
|
13
|
+
|
|
14
|
+
### Breaking
|
|
15
|
+
|
|
16
|
+
There's a breaking change for Firefox if you add your own request header or if you use scripting and want to clear the browser in your script:
|
|
17
|
+
|
|
18
|
+
* Removed the [Browsertime extension](https://github.com/sitespeedio/browsertime-extension). In the old days the extension helped Chrome and Firefox to add cookies, requestheaders, clear caches and more. However all that functionality has been implemented in CDP for Chrome and most functionality using Bidi webdriver for Firefox. At the moment we drop two things for Firefox: Add request header and clear the cache inside of scripting. We hope both soon is supported in Bidi [#2124](https://github.com/sitespeedio/browsertime/pull/2124).
|
|
19
|
+
|
|
20
|
+
* The ff-test-bidi-har-export is now the default (and only) way to get a HAR file from Firefox. It's faster than the old HAR exporter and works on both desktop and mobile. It's also is implemented using Bidi so when other browsers also support bidi they can also export a HAR [#2123](https://github.com/sitespeedio/browsertime/pull/2123).
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
* Updated the Docker container to use Chrome 125 and Firefox 126 and Edge 124 [#2125](https://github.com/sitespeedio/browsertime/pull/2125) and [#2128](https://github.com/sitespeedio/browsertime/pull/2128).
|
|
24
|
+
|
|
3
25
|
## 21.7.1 - 2024-04-03
|
|
4
26
|
### Fixed
|
|
5
27
|
* Bug fix: If you test a URL that failed, we got an error that didn't produce the browsertime.json [#2120](https://github.com/sitespeedio/browsertime/pull/2120).
|
|
6
|
-
* Updated to
|
|
28
|
+
* Updated to Selenium webdriver 4.20.0 [#2121](https://github.com/sitespeedio/browsertime/pull/2121).
|
|
7
29
|
|
|
8
30
|
## 21.7.0 - 2024-04-03
|
|
9
31
|
### Added
|
|
@@ -8,7 +8,7 @@ const log = intel.getLogger('browsertime.command.cache');
|
|
|
8
8
|
* @hideconstructor
|
|
9
9
|
*/
|
|
10
10
|
export class Cache {
|
|
11
|
-
constructor(browser, browserName,
|
|
11
|
+
constructor(browser, browserName, cdp) {
|
|
12
12
|
/**
|
|
13
13
|
* @private
|
|
14
14
|
*/
|
|
@@ -17,10 +17,6 @@ export class Cache {
|
|
|
17
17
|
* @private
|
|
18
18
|
*/
|
|
19
19
|
this.browserName = browserName;
|
|
20
|
-
/**
|
|
21
|
-
* @private
|
|
22
|
-
*/
|
|
23
|
-
this.extensionServer = extensionServer;
|
|
24
20
|
/**
|
|
25
21
|
* @private
|
|
26
22
|
*/
|
|
@@ -30,7 +26,6 @@ export class Cache {
|
|
|
30
26
|
/**
|
|
31
27
|
* Clears the browser cache. This includes both cache and cookies.
|
|
32
28
|
*
|
|
33
|
-
* For Firefox, it uses the extensionServer setup with specific options.
|
|
34
29
|
* For Chrome and Edge, it uses the Chrome DevTools Protocol (CDP) commands.
|
|
35
30
|
* If the browser is not supported, logs an error message.
|
|
36
31
|
*
|
|
@@ -40,13 +35,7 @@ export class Cache {
|
|
|
40
35
|
* @returns {Promise<void>} A promise that resolves when the cache and cookies are cleared.
|
|
41
36
|
*/
|
|
42
37
|
async clear() {
|
|
43
|
-
if (this.browserName === '
|
|
44
|
-
const options = {
|
|
45
|
-
cacheClearRaw: true,
|
|
46
|
-
browser: 'firefox'
|
|
47
|
-
};
|
|
48
|
-
return this.extensionServer.setup(undefined, this.browser, options);
|
|
49
|
-
} else if (this.browserName === 'chrome' || this.browserName === 'edge') {
|
|
38
|
+
if (this.browserName === 'chrome' || this.browserName === 'edge') {
|
|
50
39
|
await this.cdp.send('Network.enable');
|
|
51
40
|
await this.cdp.send('Network.clearBrowserCache');
|
|
52
41
|
return this.cdp.send('Network.clearBrowserCookies');
|
|
@@ -58,7 +47,6 @@ export class Cache {
|
|
|
58
47
|
/**
|
|
59
48
|
* Clears the browser cache while keeping the cookies.
|
|
60
49
|
*
|
|
61
|
-
* For Firefox, it uses the extensionServer setup with specific options.
|
|
62
50
|
* For Chrome and Edge, it uses the Chrome DevTools Protocol (CDP) command to clear the cache.
|
|
63
51
|
* If the browser is not supported, logs an error message.
|
|
64
52
|
*
|
|
@@ -68,13 +56,7 @@ export class Cache {
|
|
|
68
56
|
* @returns {Promise<void>} A promise that resolves when the cache is cleared but cookies are kept.
|
|
69
57
|
*/
|
|
70
58
|
async clearKeepCookies() {
|
|
71
|
-
if (this.browserName === '
|
|
72
|
-
const options = {
|
|
73
|
-
clearCacheKeepCookies: true,
|
|
74
|
-
browser: 'firefox'
|
|
75
|
-
};
|
|
76
|
-
return this.extensionServer.setup(undefined, this.browser, options);
|
|
77
|
-
} else if (this.browserName === 'chrome' || this.browserName === 'edge') {
|
|
59
|
+
if (this.browserName === 'chrome' || this.browserName === 'edge') {
|
|
78
60
|
await this.cdp.send('Network.enable');
|
|
79
61
|
return this.cdp.send('Network.clearBrowserCache');
|
|
80
62
|
} else {
|
|
@@ -41,7 +41,6 @@ export class Measure {
|
|
|
41
41
|
pageCompleteCheck,
|
|
42
42
|
result,
|
|
43
43
|
engineDelegate,
|
|
44
|
-
extensionServer,
|
|
45
44
|
storageManager,
|
|
46
45
|
videos,
|
|
47
46
|
scriptsByCategory,
|
|
@@ -87,10 +86,6 @@ export class Measure {
|
|
|
87
86
|
* @private
|
|
88
87
|
*/
|
|
89
88
|
this.recordVideo = options.visualMetrics || options.video;
|
|
90
|
-
/**
|
|
91
|
-
* @private
|
|
92
|
-
*/
|
|
93
|
-
this.extensionServer = extensionServer;
|
|
94
89
|
/**
|
|
95
90
|
* @private
|
|
96
91
|
*/
|
|
@@ -244,17 +239,13 @@ export class Measure {
|
|
|
244
239
|
*/
|
|
245
240
|
async _navigate(url) {
|
|
246
241
|
log.info('Navigating to url %s iteration %s', url, this.index);
|
|
247
|
-
if (
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
// There's a bug that we introduced when moving cookie handling to CDP
|
|
242
|
+
if (
|
|
243
|
+
this.numberOfVisitedPages === 0 && // There's a bug that we introduced when moving cookie handling to CDP
|
|
251
244
|
// and this is the hack to fix that.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
)
|
|
256
|
-
await this.engineDelegate.setCookies(url, this.options.cookie);
|
|
257
|
-
}
|
|
245
|
+
((this.options.cookie && this.options.browser === 'chrome') ||
|
|
246
|
+
this.options.browser === 'edge')
|
|
247
|
+
) {
|
|
248
|
+
await this.engineDelegate.setCookies(url, this.options.cookie);
|
|
258
249
|
}
|
|
259
250
|
if (this.numberOfVisitedPages === 0) {
|
|
260
251
|
await this.engineDelegate.beforeStartIteration(this.browser, this.index);
|
|
@@ -302,11 +293,6 @@ export class Measure {
|
|
|
302
293
|
log.info('Start to measure');
|
|
303
294
|
}
|
|
304
295
|
|
|
305
|
-
// On the first page of an iteration, do what you need to do!
|
|
306
|
-
if (this.numberOfVisitedPages === 0 && url) {
|
|
307
|
-
// We can only setup the extension if we have a URL at the moment
|
|
308
|
-
await this.extensionServer.setup(url, this.browser, this.options);
|
|
309
|
-
}
|
|
310
296
|
if (this.numberOfVisitedPages === 0) {
|
|
311
297
|
await this.engineDelegate.beforeStartIteration(this.browser, this.index);
|
|
312
298
|
}
|
|
@@ -40,7 +40,6 @@ export class Commands {
|
|
|
40
40
|
result,
|
|
41
41
|
storageManager,
|
|
42
42
|
pageCompleteCheck,
|
|
43
|
-
extensionServer,
|
|
44
43
|
context,
|
|
45
44
|
videos,
|
|
46
45
|
screenshotManager,
|
|
@@ -55,7 +54,6 @@ export class Commands {
|
|
|
55
54
|
pageCompleteCheck,
|
|
56
55
|
result,
|
|
57
56
|
engineDelegate,
|
|
58
|
-
extensionServer,
|
|
59
57
|
storageManager,
|
|
60
58
|
videos,
|
|
61
59
|
scriptsByCategory,
|
|
@@ -181,7 +179,7 @@ export class Commands {
|
|
|
181
179
|
* Manages the browser's cache.
|
|
182
180
|
* @type {Cache}
|
|
183
181
|
*/
|
|
184
|
-
this.cache = new Cache(browser, options.browser,
|
|
182
|
+
this.cache = new Cache(browser, options.browser, cdp);
|
|
185
183
|
|
|
186
184
|
/**
|
|
187
185
|
* Adds metadata to the user journey.
|
|
@@ -8,7 +8,6 @@ import { SeleniumRunner } from '../seleniumRunner.js';
|
|
|
8
8
|
import { preURL } from '../../support/preURL.js';
|
|
9
9
|
import { setResourceTimingBufferSize } from '../../support/setResourceTimingBufferSize.js';
|
|
10
10
|
import { ScreenshotManager } from '../../screenshot/index.js';
|
|
11
|
-
import { ExtensionServer } from '../../extensionserver/index.js';
|
|
12
11
|
import { Video } from '../../video/video.js';
|
|
13
12
|
import { stop } from '../../support/stop.js';
|
|
14
13
|
|
|
@@ -79,7 +78,6 @@ export class Iteration {
|
|
|
79
78
|
const result = [];
|
|
80
79
|
const batteryTemperature = {};
|
|
81
80
|
|
|
82
|
-
const extensionServer = new ExtensionServer(options);
|
|
83
81
|
const engineDelegate = this.engineDelegate;
|
|
84
82
|
|
|
85
83
|
try {
|
|
@@ -112,7 +110,6 @@ export class Iteration {
|
|
|
112
110
|
result,
|
|
113
111
|
this.storageManager,
|
|
114
112
|
this.pageCompleteCheck,
|
|
115
|
-
extensionServer,
|
|
116
113
|
context,
|
|
117
114
|
videos,
|
|
118
115
|
screenshotManager,
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import path from 'node:path';
|
|
4
1
|
import { platform } from 'node:os';
|
|
5
2
|
import {
|
|
6
3
|
ServiceBuilder,
|
|
@@ -18,12 +15,10 @@ import { disableTrackingProtectionPreferences } from '../settings/disableTrackin
|
|
|
18
15
|
import { toArray } from '../../support/util.js';
|
|
19
16
|
import { Android, isAndroidConfigured } from '../../android/index.js';
|
|
20
17
|
const log = intel.getLogger('browsertime.firefox');
|
|
21
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
22
18
|
|
|
23
19
|
export async function configureBuilder(builder, baseDir, options) {
|
|
24
20
|
// Here we configure everything that we need to start Firefox
|
|
25
21
|
const firefoxConfig = options.firefox || {};
|
|
26
|
-
const moduleRootPath = resolve(__dirname, '..', '..', '..');
|
|
27
22
|
|
|
28
23
|
let geckodriverPath = get(firefoxConfig, 'geckodriverPath');
|
|
29
24
|
if (!geckodriverPath) {
|
|
@@ -112,15 +107,6 @@ export async function configureBuilder(builder, baseDir, options) {
|
|
|
112
107
|
ffOptions.setPreference('detach', true);
|
|
113
108
|
}
|
|
114
109
|
|
|
115
|
-
// Browsertime own extension, only load it when we need it
|
|
116
|
-
// We should be able to only install it only when needed, but that could break scripting
|
|
117
|
-
|
|
118
|
-
if (!firefoxConfig.disableBrowsertimeExtension) {
|
|
119
|
-
ffOptions.addExtensions(
|
|
120
|
-
resolve(moduleRootPath, 'vendor', 'browsertime-0.18.0-an+fx.xpi')
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
110
|
if (options.extension) {
|
|
125
111
|
const extensions = Array.isArray(options.extension)
|
|
126
112
|
? options.extension
|
|
@@ -200,33 +186,6 @@ export async function configureBuilder(builder, baseDir, options) {
|
|
|
200
186
|
|
|
201
187
|
ffOptions.enableBidi();
|
|
202
188
|
|
|
203
|
-
// Enable bidi for HAR support
|
|
204
|
-
if (firefoxConfig.bidihar) {
|
|
205
|
-
/* We do not need to do anything for bidi har */
|
|
206
|
-
} else {
|
|
207
|
-
if (!options.skipHar) {
|
|
208
|
-
if (isAndroidConfigured(options)) {
|
|
209
|
-
log.info('Skip install HAR trigger on Android');
|
|
210
|
-
} else {
|
|
211
|
-
// Hack for opening the toolbar
|
|
212
|
-
// In Firefox 61 we need to have devtools open but do not need to choose netmonitor
|
|
213
|
-
// ffOptions.setPreference('devtools.toolbox.selectedTool', 'netmonitor');
|
|
214
|
-
if (!options.debug) {
|
|
215
|
-
ffOptions.setPreference('devtools.toolbox.footer.height', 0);
|
|
216
|
-
ffOptions.addArguments('-devtools');
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
ffOptions.addExtensions(
|
|
220
|
-
resolve(
|
|
221
|
-
moduleRootPath,
|
|
222
|
-
'vendor',
|
|
223
|
-
'har_export_trigger-0.6.1-an+fx.xpi'
|
|
224
|
-
)
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
189
|
if (firefoxConfig.args) {
|
|
231
190
|
ffOptions.addArguments(firefoxConfig.args);
|
|
232
191
|
}
|
|
@@ -14,7 +14,6 @@ import { FirefoxBidi } from '../firefoxBidi.js';
|
|
|
14
14
|
import { MemoryReport } from '../memoryReport.js';
|
|
15
15
|
import { PerfStats } from '../perfStats.js';
|
|
16
16
|
import { NetworkManager } from '../networkManager.js';
|
|
17
|
-
import { getHAR } from '../getHAR.js';
|
|
18
17
|
|
|
19
18
|
const log = intel.getLogger('browsertime.firefox');
|
|
20
19
|
const rename = promisify(_rename);
|
|
@@ -55,7 +54,7 @@ export class Firefox {
|
|
|
55
54
|
async afterBrowserStart(runner) {
|
|
56
55
|
this.windowId = await runner.getDriver().getWindowHandle();
|
|
57
56
|
|
|
58
|
-
if (this.
|
|
57
|
+
if (!this.options.skipHar) {
|
|
59
58
|
this.har = new adapters.SeleniumBiDiHarRecorder({
|
|
60
59
|
browsingContextIds: [this.windowId],
|
|
61
60
|
debugLogs:
|
|
@@ -128,7 +127,7 @@ export class Firefox {
|
|
|
128
127
|
});
|
|
129
128
|
`);
|
|
130
129
|
|
|
131
|
-
if (!this.skipHar
|
|
130
|
+
if (!this.skipHar) {
|
|
132
131
|
await this.har.startRecording();
|
|
133
132
|
}
|
|
134
133
|
|
|
@@ -228,19 +227,13 @@ export class Firefox {
|
|
|
228
227
|
}
|
|
229
228
|
result.cpu = powerusage;
|
|
230
229
|
|
|
231
|
-
if (
|
|
232
|
-
this.skipHar ||
|
|
233
|
-
(isAndroidConfigured(this.options) && !this.firefoxConfig.bidihar)
|
|
234
|
-
) {
|
|
230
|
+
if (this.skipHar) {
|
|
235
231
|
if (result.alias && !this.aliasAndUrl[result.alias]) {
|
|
236
232
|
this.aliasAndUrl[result.alias] = result.url;
|
|
237
233
|
}
|
|
238
234
|
return result;
|
|
239
235
|
} else {
|
|
240
|
-
|
|
241
|
-
const har = this.firefoxConfig.bidihar
|
|
242
|
-
? await this.har.stopRecording()
|
|
243
|
-
: await getHAR(runner, this.includeResponseBodies);
|
|
236
|
+
const har = await this.har.stopRecording();
|
|
244
237
|
if (har.log.pages.length > 0) {
|
|
245
238
|
// Hack to add the URL from a SPA
|
|
246
239
|
if (result.alias && !this.aliasAndUrl[result.alias]) {
|
package/lib/support/cli.js
CHANGED
|
@@ -452,12 +452,6 @@ export function parseCommandLine() {
|
|
|
452
452
|
type: 'boolean',
|
|
453
453
|
group: 'firefox'
|
|
454
454
|
})
|
|
455
|
-
.option('firefox.bidihar', {
|
|
456
|
-
describe: 'Use the new bidi HAR generator',
|
|
457
|
-
default: false,
|
|
458
|
-
type: 'boolean',
|
|
459
|
-
group: 'firefox'
|
|
460
|
-
})
|
|
461
455
|
.option('firefox.windowRecorder', {
|
|
462
456
|
describe:
|
|
463
457
|
'Use the internal compositor-based Firefox window recorder to emit PNG files for each ' +
|
|
@@ -552,11 +546,6 @@ export function parseCommandLine() {
|
|
|
552
546
|
'timestamp,nsHttp:5,cache2:5,nsSocketTransport:5,nsHostResolver:5',
|
|
553
547
|
group: 'firefox'
|
|
554
548
|
})
|
|
555
|
-
.option('firefox.disableBrowsertimeExtension', {
|
|
556
|
-
describe: 'Disable installing the browsertime extension.',
|
|
557
|
-
type: 'boolean',
|
|
558
|
-
group: 'firefox'
|
|
559
|
-
})
|
|
560
549
|
.option('firefox.noDefaultPrefs', {
|
|
561
550
|
describe: 'Prevents browsertime from setting its default preferences.',
|
|
562
551
|
default: false,
|
|
@@ -1087,11 +1076,11 @@ export function parseCommandLine() {
|
|
|
1087
1076
|
.option('requestheader', {
|
|
1088
1077
|
alias: 'r',
|
|
1089
1078
|
describe:
|
|
1090
|
-
'Request header that will be added to the request. Add multiple instances to add multiple request headers. Works for
|
|
1079
|
+
'Request header that will be added to the request. Add multiple instances to add multiple request headers. Works for Edge and Chrome. Use the following format key:value'
|
|
1091
1080
|
})
|
|
1092
1081
|
.option('cookie', {
|
|
1093
1082
|
describe:
|
|
1094
|
-
'Cookie that will be added to the request. Add multiple instances to add multiple request cookies. Works for Firefox and
|
|
1083
|
+
'Cookie that will be added to the request. Add multiple instances to add multiple request cookies. Works for Firefox, Chrome and Edge. Use the following format cookieName=cookieValue'
|
|
1095
1084
|
})
|
|
1096
1085
|
.option('injectJs', {
|
|
1097
1086
|
describe:
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browsertime",
|
|
3
3
|
"description": "Get performance metrics from your web page using Browsertime.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "22.1.0",
|
|
5
5
|
"bin": "./bin/browsertime.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"types": "./types/scripting.d.ts",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@cypress/xvfb": "1.2.4",
|
|
10
10
|
"@devicefarmer/adbkit": "3.2.6",
|
|
11
|
-
"@sitespeed.io/chromedriver": "
|
|
12
|
-
"@sitespeed.io/edgedriver": "
|
|
11
|
+
"@sitespeed.io/chromedriver": "125.0.6422-60",
|
|
12
|
+
"@sitespeed.io/edgedriver": "125.0.2535-47",
|
|
13
13
|
"@sitespeed.io/geckodriver": "0.34.0",
|
|
14
14
|
"@sitespeed.io/throttle": "5.0.0",
|
|
15
15
|
"@sitespeed.io/tracium": "0.3.3",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"dayjs": "1.11.10",
|
|
20
20
|
"execa": "8.0.1",
|
|
21
21
|
"fast-stats": "0.0.6",
|
|
22
|
-
"ff-test-bidi-har-export": "0.0.
|
|
22
|
+
"ff-test-bidi-har-export": "0.0.13",
|
|
23
23
|
"find-up": "7.0.0",
|
|
24
24
|
"get-port": "7.0.0",
|
|
25
25
|
"hasbin": "1.2.3",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"lodash.merge": "4.6.2",
|
|
31
31
|
"lodash.pick": "4.4.0",
|
|
32
32
|
"lodash.set": "4.3.2",
|
|
33
|
-
"selenium-webdriver": "4.
|
|
33
|
+
"selenium-webdriver": "4.21.0",
|
|
34
34
|
"yargs": "17.7.2"
|
|
35
35
|
},
|
|
36
36
|
"optionalDependencies": {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @hideconstructor
|
|
7
7
|
*/
|
|
8
8
|
export class Cache {
|
|
9
|
-
constructor(browser: any, browserName: any,
|
|
9
|
+
constructor(browser: any, browserName: any, cdp: any);
|
|
10
10
|
/**
|
|
11
11
|
* @private
|
|
12
12
|
*/
|
|
@@ -15,10 +15,6 @@ export class Cache {
|
|
|
15
15
|
* @private
|
|
16
16
|
*/
|
|
17
17
|
private browserName;
|
|
18
|
-
/**
|
|
19
|
-
* @private
|
|
20
|
-
*/
|
|
21
|
-
private extensionServer;
|
|
22
18
|
/**
|
|
23
19
|
* @private
|
|
24
20
|
*/
|
|
@@ -26,7 +22,6 @@ export class Cache {
|
|
|
26
22
|
/**
|
|
27
23
|
* Clears the browser cache. This includes both cache and cookies.
|
|
28
24
|
*
|
|
29
|
-
* For Firefox, it uses the extensionServer setup with specific options.
|
|
30
25
|
* For Chrome and Edge, it uses the Chrome DevTools Protocol (CDP) commands.
|
|
31
26
|
* If the browser is not supported, logs an error message.
|
|
32
27
|
*
|
|
@@ -39,7 +34,6 @@ export class Cache {
|
|
|
39
34
|
/**
|
|
40
35
|
* Clears the browser cache while keeping the cookies.
|
|
41
36
|
*
|
|
42
|
-
* For Firefox, it uses the extensionServer setup with specific options.
|
|
43
37
|
* For Chrome and Edge, it uses the Chrome DevTools Protocol (CDP) command to clear the cache.
|
|
44
38
|
* If the browser is not supported, logs an error message.
|
|
45
39
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../lib/core/engine/command/cache.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH;IACE,
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../lib/core/engine/command/cache.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH;IACE,sDAaC;IAZC;;OAEG;IACH,gBAAsB;IACtB;;OAEG;IACH,oBAA8B;IAC9B;;OAEG;IACH,YAAc;IAGhB;;;;;;;;;;OAUG;IACH,SAFa,QAAQ,IAAI,CAAC,CAUzB;IAED;;;;;;;;;;OAUG;IACH,oBAFa,QAAQ,IAAI,CAAC,CASzB;CACF"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @hideconstructor
|
|
7
7
|
*/
|
|
8
8
|
export class Measure {
|
|
9
|
-
constructor(browser: any, index: any, pageCompleteCheck: any, result: any, engineDelegate: any,
|
|
9
|
+
constructor(browser: any, index: any, pageCompleteCheck: any, result: any, engineDelegate: any, storageManager: any, videos: any, scriptsByCategory: any, asyncScriptsByCategory: any, postURLScripts: any, context: any, screenshotManager: any, options: any);
|
|
10
10
|
/**
|
|
11
11
|
* @private
|
|
12
12
|
*/
|
|
@@ -43,10 +43,6 @@ export class Measure {
|
|
|
43
43
|
* @private
|
|
44
44
|
*/
|
|
45
45
|
private recordVideo;
|
|
46
|
-
/**
|
|
47
|
-
* @private
|
|
48
|
-
*/
|
|
49
|
-
private extensionServer;
|
|
50
46
|
/**
|
|
51
47
|
* @private
|
|
52
48
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../../lib/core/engine/command/measure.js"],"names":[],"mappings":"AA6BA;;;;;;GAMG;AACH;IACE,
|
|
1
|
+
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../../lib/core/engine/command/measure.js"],"names":[],"mappings":"AA6BA;;;;;;GAMG;AACH;IACE,gQAuGC;IAxFC;;OAEG;IACH,gBAAsB;IACtB;;OAEG;IACH,0BAA0C;IAC1C;;OAEG;IACH,cAAkB;IAClB;;OAEG;IACH,eAAoB;IACpB;;OAEG;IACH,uBAAoC;IACpC;;OAEG;IACH,gBAAsB;IACtB;;OAEG;IACH,0BAA0C;IAC1C;;OAEG;IACH,uBAAoC;IACpC;;OAEG;IACH,oBAAyD;IACzD;;OAEG;IACH,eAAoB;IACpB;;OAEG;IACH,0BAA0C;IAC1C;;OAEG;IACH,+BAAoD;IACpD;;OAEG;IACH,uBAAoC;IACpC;;OAEG;IACH,gBAAsB;IACtB;;OAEG;IACH,8BAA8B;IAC9B;;OAEG;IACH,6BAA6B;IAC7B;;OAEG;IACH,uBAA2B;IAC3B;;OAEG;IACH,mBAAoB;IACpB;;OAEG;IACH,gBAA6D;IAC7D;;OAEG;IACH,2BAAsE;IACtE;;OAEG;IACH,uBAA8D;IAC9D;;OAEG;IACH,2BAAqE;IAGvE;;;OAGG;IACH,oBAsBC;IArBC,aAAuE;IAuBzE;;;OAGG;IACH,mBAKC;IAED;;;OAGG;IACH,eAyBC;IAED;;;OAGG;IACH,iBAQC;IAED;;;;;;;;;;;;OAYG;IACH,kBAmBC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,kBALW,MAAM,kBACN,MAAM,GAEJ,QAAQ,IAAI,CAAC,CAmFzB;IAED;;;;;;;;OAQG;IACH,0BAJW,MAAM,gBAiBhB;IACD;;;;;;;;;OASG;IACH,qBAJW,MAAM,gBAwEhB;IAED;;;;;;;OAOG;IACH,UAJW,MAAM,oBAYhB;IAED;;;;;;;OAOG;IACH,6BAOC;IAED;;;OAGG;IACH,gBA4KC;CACF;sBAjqBqB,yBAAyB"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @hideconstructor
|
|
4
4
|
*/
|
|
5
5
|
export class Commands {
|
|
6
|
-
constructor(browser: any, engineDelegate: any, index: any, result: any, storageManager: any, pageCompleteCheck: any,
|
|
6
|
+
constructor(browser: any, engineDelegate: any, index: any, result: any, storageManager: any, pageCompleteCheck: any, context: any, videos: any, screenshotManager: any, scriptsByCategory: any, asyncScriptsByCategory: any, postURLScripts: any, options: any);
|
|
7
7
|
profiler: GeckoProfilerCommand;
|
|
8
8
|
/**
|
|
9
9
|
* Manages Chrome trace functionality, enabling custom profiling and trace collection in Chrome.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../lib/core/engine/commands.js"],"names":[],"mappings":"AA8BA;;;GAGG;AACH;IACE,
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../lib/core/engine/commands.js"],"names":[],"mappings":"AA8BA;;;GAGG;AACH;IACE,gQA4OC;IA3MC,+BAMC;IAMD;;;OAGG;IACH,OAFU,WAAW,CAE+C;IAEpE;;;OAGG;IACH,OAFU,KAAK,CAEmC;IAElD;;;OAGG;IACH,QAFU,MAAM,CAE0B;IAE1C;;;OAGG;IACH,SAFU,OAAO,CAEkB;IAEnC;;;OAGG;IACH,MAFU,IAAI,CAEkC;IAEhD;;;OAGG;IACH,SAFU,OAAO,CAEK;IAEtB;;;;;;;;OAQG;IACH,mBAA+C;IAE/C;;;OAGG;IACH,YAFU,UAAU,CAEwC;IAE5D;;;;;OAKG;IACH,gBAAyC;IAEzC;;;;;OAKG;IACH,wBAAmD;IAEnD;;;OAGG;IACH,IAFU,UAAU,CAEgC;IAEpD;;;OAGG;IACH,QAFU,MAAM,CAMf;IAED;;;OAGG;IACH,KAFU,GAAG,CAEc;IAE3B;;;OAGG;IACH,WAFU,SAAS,CAEoB;IAEvC;;;OAGG;IACH,OAFU,KAAK,CAEsC;IAErD;;;OAGG;IACH,MAFU,IAAI,CAEQ;IAEtB;;;OAGG;IACH,YAFU,UAAU,CAE+C;IAEnE;;;OAGG;IACH,KAFU,8BAA8B,CAE1B;IAEd;;;;OAIG;IACH,MAFU,IAAI,CAEuC;IAErD;;;OAGG;IACH,SAFU,cAAc,CAEkB;IAE1C;;;;OAIG;IACH,OAFW,KAAK,CAEwB;IAExC;;;OAGG;IACH,WA0BC;IAED;;;OAGG;IACH,QAFU,MAAM,CAEiB;IAEjC;;;;OAIG;IACH,QAHU,OAAO,CAGiB;IAElC;;;OAGG;IACH,SAFU,OAAO,CAEkB;CAEtC;sDAnPqD,4BAA4B;4BAXtD,0BAA0B;sBAhBhC,oBAAoB;uBAwBnB,qBAAqB;wBAzBpB,sBAAsB;qBAGzB,mBAAmB;wBAChB,sBAAsB;2BAsBnB,yBAAyB;2BArBzB,yBAAyB;uBAC7B,qBAAqB;oBAExB,kBAAkB;mCAGH,wBAAwB;sBAFrC,oBAAoB;qBACrB,mBAAmB;2BAHb,yBAAyB;+CASL,qCAAqC;qBAF/D,mBAAmB;+BACT,sBAAsB;sBAF/B,oBAAoB;uBADnB,qBAAqB;wBAbpB,sBAAsB;wBAGtB,sBAAsB"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { promisify } from 'node:util';
|
|
2
|
-
import { createServer } from 'node:http';
|
|
3
|
-
|
|
4
|
-
export async function startServer() {
|
|
5
|
-
const server = createServer((request, res) => {
|
|
6
|
-
res.writeHead(200, {
|
|
7
|
-
'Content-Type': 'text/html',
|
|
8
|
-
'Referrer-Policy': 'no-referrer'
|
|
9
|
-
});
|
|
10
|
-
res.end('<html><body></body></html>');
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
const listen = promisify(server.listen.bind(server));
|
|
14
|
-
await listen();
|
|
15
|
-
return server;
|
|
16
|
-
}
|
|
17
|
-
export async function stopServer(server) {
|
|
18
|
-
const close = promisify(server.close.bind(server));
|
|
19
|
-
return close();
|
|
20
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { startServer, stopServer } from './httpServer.js';
|
|
2
|
-
import { setup } from './setup.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Create a ExtensionServer. The extension server helps us with
|
|
6
|
-
* running the Browsertime extension, making it possible to
|
|
7
|
-
* use a WebExtension to prepare our tests.
|
|
8
|
-
* @class
|
|
9
|
-
*/
|
|
10
|
-
export class ExtensionServer {
|
|
11
|
-
constructor(options) {
|
|
12
|
-
this.options = options;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
_useServer(newOptions) {
|
|
16
|
-
const options = newOptions || this.options;
|
|
17
|
-
return options.browser === 'firefox' &&
|
|
18
|
-
(options.cacheClearRaw ||
|
|
19
|
-
options.requestheader ||
|
|
20
|
-
options.clearCacheKeepCookies)
|
|
21
|
-
? true
|
|
22
|
-
: false;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async _start() {
|
|
26
|
-
if (!this.extensionServer) {
|
|
27
|
-
this.extensionServer = await startServer();
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async _stop() {
|
|
32
|
-
if (this.extensionServer) {
|
|
33
|
-
await stopServer(this.extensionServer);
|
|
34
|
-
this.extensionServer = undefined;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async setup(url, browser, setupOptions) {
|
|
39
|
-
if (this._useServer(setupOptions)) {
|
|
40
|
-
await this._start();
|
|
41
|
-
const port = this.extensionServer.address().port;
|
|
42
|
-
await setup(url, browser, port, setupOptions);
|
|
43
|
-
return this._stop();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { format } from 'node:url';
|
|
2
|
-
import intel from 'intel';
|
|
3
|
-
import { toArray } from '../support/util.js';
|
|
4
|
-
const log = intel.getLogger('browsertime');
|
|
5
|
-
const delay = ms => new Promise(res => setTimeout(res, ms));
|
|
6
|
-
|
|
7
|
-
function generateURL(port, testUrl, options) {
|
|
8
|
-
const query = {};
|
|
9
|
-
|
|
10
|
-
if (options.requestheader) {
|
|
11
|
-
query.rh = toArray(options.requestheader);
|
|
12
|
-
}
|
|
13
|
-
if (options.cacheClearRaw) {
|
|
14
|
-
query.clear = 'true';
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (options.clearCacheKeepCookies) {
|
|
18
|
-
query.clearCacheKeepCookies = 'true';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (options.basicAuth) {
|
|
22
|
-
query.ba = options.basicAuth + '@' + testUrl;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return format({
|
|
26
|
-
protocol: 'http',
|
|
27
|
-
hostname: '127.0.0.1',
|
|
28
|
-
port,
|
|
29
|
-
query
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export async function setup(url, browser, port, options) {
|
|
34
|
-
const configUrl = generateURL(port, url, options);
|
|
35
|
-
log.debug('Configuring browser plugin via %s', configUrl);
|
|
36
|
-
await browser.loadAndWait(configUrl);
|
|
37
|
-
// Add some time to make sure the cache is cleared etc
|
|
38
|
-
await delay(500);
|
|
39
|
-
}
|
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
|
|
Binary file
|
|
Binary file
|