browsertime 14.5.0 → 14.8.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 +28 -1
- package/bin/browsertime.js +1 -1
- package/lib/android/index.js +1 -1
- package/lib/chrome/har.js +4 -4
- package/lib/chrome/longTaskMetrics.js +1 -1
- package/lib/chrome/speedline.js +2 -2
- package/lib/chrome/webdriver/builder.js +1 -1
- package/lib/chrome/webdriver/setupChromiumOptions.js +7 -2
- package/lib/connectivity/trafficShapeParser.js +2 -2
- package/lib/connectivity/tsProxy.js +3 -3
- package/lib/core/engine/command/measure.js +16 -10
- package/lib/core/engine/command/mouse/clickAndHold.js +4 -16
- package/lib/core/engine/command/switch.js +2 -8
- package/lib/core/engine/iteration.js +4 -5
- package/lib/core/engine/run.js +2 -2
- package/lib/core/seleniumRunner.js +23 -22
- package/lib/core/webdriver/index.js +1 -1
- package/lib/edge/webdriver/builder.js +1 -1
- package/lib/extensionserver/setup.js +1 -1
- package/lib/firefox/geckoProfiler.js +6 -5
- package/lib/firefox/getHAR.js +1 -1
- package/lib/firefox/memoryReport.js +5 -1
- package/lib/firefox/webdriver/builder.js +12 -7
- package/lib/firefox/webdriver/firefox.js +6 -7
- package/lib/safari/webdriver/builder.js +1 -1
- package/lib/support/browserScript.js +1 -1
- package/lib/support/cli.js +12 -0
- package/lib/support/engineUtils.js +1 -1
- package/lib/support/getViewPort.js +1 -1
- package/lib/support/har/index.js +13 -14
- package/lib/support/pathToFolder.js +4 -10
- package/lib/support/preURL.js +1 -1
- package/lib/support/setResourceTimingBufferSize.js +1 -1
- package/lib/support/statistics.js +1 -1
- package/lib/support/stop.js +1 -1
- package/lib/support/storageManager.js +5 -10
- package/lib/video/postprocessing/finetune/addTextToVideo.js +1 -1
- package/lib/video/postprocessing/finetune/convertFps.js +1 -1
- package/lib/video/postprocessing/finetune/getFont.js +1 -1
- package/lib/video/postprocessing/finetune/getTimingMetrics.js +5 -4
- package/lib/video/postprocessing/finetune/index.js +1 -1
- package/lib/video/postprocessing/finetune/removeOrange.js +1 -1
- package/lib/video/postprocessing/visualmetrics/extraMetrics.js +1 -1
- package/lib/video/postprocessing/visualmetrics/getVideoMetrics.js +1 -1
- package/lib/video/screenRecording/desktop/ffmpegRecorder.js +3 -3
- package/lib/video/screenRecording/desktop/osx/getSPDisplaysDataType.js +1 -1
- package/lib/video/screenRecording/desktop/osx/getScreen.js +1 -1
- package/lib/video/screenRecording/firefox/firefoxWindowRecorder.js +2 -2
- package/lib/video/screenRecording/setOrangeBackground.js +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Browsertime changelog (we do [semantic versioning](https://semver.org))
|
|
2
2
|
|
|
3
|
+
## 14.8.0 - 2021-10-27
|
|
4
|
+
### Added
|
|
5
|
+
* New Edgedriver 95 and Edge 95 in the Docker container [#1665](https://github.com/sitespeedio/browsertime/pull/1665).
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
* Fix for storing Firefox memory report and geckoprofile on Android 10+. Thank you [Andrew Creskey](https://github.com/acreskeyMoz) for PR [#1663](https://github.com/sitespeedio/browsertime/pull/1663).
|
|
9
|
+
|
|
10
|
+
## 14.7.0 - 2021-10-20
|
|
11
|
+
### Added
|
|
12
|
+
* Updated to Chromedriver 95. Added Chrome 95 in the Docker container.
|
|
13
|
+
|
|
14
|
+
## 14.6.1 - 2021-10-18
|
|
15
|
+
### Fixed
|
|
16
|
+
* If loading the URL fails (we get an exception, the browser crashes etc) make sure we stop the video correctly so it can be used [#1657](https://github.com/sitespeedio/browsertime/pull/1657).
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## 14.6.0 - 2021-10-13
|
|
20
|
+
### Added
|
|
21
|
+
* Updated to Selenium 4.0.0 [#1655](https://github.com/sitespeedio/browsertime/pull/1655).
|
|
22
|
+
* You can skip setting Browsertime default Firefox preferences with `--firefox.noDefaultPrefs`, thank you [Gregory Mierzwinski](https://github.com/gmierz) for PR [#1650](https://github.com/sitespeedio/browsertime/pull/1650).
|
|
23
|
+
* You can skip setting Browsertime default Chrome options with `--chrome.noDefaultOptions`, fixed in [#1651](https://github.com/sitespeedio/browsertime/pull/1651).
|
|
24
|
+
* Updated to Firefox 93 in the Docker container.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
* Updated eslint and prettier dependencies [#1652](https://github.com/sitespeedio/browsertime/pull/1652).
|
|
28
|
+
* Log Firefox preference and Chrome args on debug level [#1654](https://github.com/sitespeedio/browsertime/pull/1654)
|
|
3
29
|
## 14.5.0 - 2021-09-30
|
|
4
30
|
### Added
|
|
5
31
|
* Added CSS selector support for mouse commands [#1645](https://github.com/sitespeedio/browsertime/pull/1645)
|
|
@@ -9,7 +35,8 @@
|
|
|
9
35
|
|
|
10
36
|
## 14.4.0 - 2021-09-22
|
|
11
37
|
### Added
|
|
12
|
-
* Updated to
|
|
38
|
+
* Updated to Ch
|
|
39
|
+
romedriver 94 and Chrome 94 in the Docker container [#1643](https://github.com/sitespeedio/browsertime/pull/1643).
|
|
13
40
|
## 14.3.0 - 2021-09-16
|
|
14
41
|
### Added
|
|
15
42
|
* Update to Edgedriver 93. Update to Edge 93 in the Docker container [#1641](https://github.com/sitespeedio/browsertime/pull/1641).
|
package/bin/browsertime.js
CHANGED
|
@@ -11,7 +11,7 @@ const fs = require('fs');
|
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const log = require('intel').getLogger('browsertime');
|
|
13
13
|
const engineUtils = require('../lib/support/engineUtils');
|
|
14
|
-
const AsyncFunction = Object.getPrototypeOf(async function() {}).constructor;
|
|
14
|
+
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
|
|
15
15
|
const delay = ms => new Promise(res => setTimeout(res, ms));
|
|
16
16
|
|
|
17
17
|
async function parseUserScripts(scripts) {
|
package/lib/android/index.js
CHANGED
package/lib/chrome/har.js
CHANGED
|
@@ -5,7 +5,7 @@ const perflogParser = require('chrome-har');
|
|
|
5
5
|
const harBuilder = require('../support/har');
|
|
6
6
|
const { Type } = require('selenium-webdriver').logging;
|
|
7
7
|
|
|
8
|
-
module.exports = async function(
|
|
8
|
+
module.exports = async function (
|
|
9
9
|
runner,
|
|
10
10
|
result,
|
|
11
11
|
index,
|
|
@@ -38,9 +38,9 @@ module.exports = async function(
|
|
|
38
38
|
await cdpClient.setResponseBodies(har);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
const versionInfo = (
|
|
42
|
-
'Browser.getVersion'
|
|
43
|
-
)
|
|
41
|
+
const versionInfo = (
|
|
42
|
+
await cdpClient.send('Browser.getVersion')
|
|
43
|
+
).product.split('/');
|
|
44
44
|
const info = {
|
|
45
45
|
name: versionInfo[0],
|
|
46
46
|
version: versionInfo[1]
|
package/lib/chrome/speedline.js
CHANGED
|
@@ -18,13 +18,13 @@ function pad(n) {
|
|
|
18
18
|
* Use SpeedLine to analyse the Chrome trace log to get Visual Metrics.
|
|
19
19
|
* Not as good as using a video but maybe usable in some cases.
|
|
20
20
|
*/
|
|
21
|
-
module.exports = async function(trace, result, index) {
|
|
21
|
+
module.exports = async function (trace, result, index) {
|
|
22
22
|
try {
|
|
23
23
|
const navStart = trace.traceEvents.filter(
|
|
24
24
|
task =>
|
|
25
25
|
task.cat === 'blink.user_timing' && task.name === 'navigationStart'
|
|
26
26
|
);
|
|
27
|
-
navStart.sort(function(a, b) {
|
|
27
|
+
navStart.sort(function (a, b) {
|
|
28
28
|
return a.ts - b.ts;
|
|
29
29
|
});
|
|
30
30
|
log.debug('Get Speedline result from the trace');
|
|
@@ -14,7 +14,7 @@ let hasConfiguredChromeDriverService = false;
|
|
|
14
14
|
* @param builder
|
|
15
15
|
* @param {Object} options the options for a web driver.
|
|
16
16
|
*/
|
|
17
|
-
module.exports.configureBuilder = function(builder, baseDir, options) {
|
|
17
|
+
module.exports.configureBuilder = function (builder, baseDir, options) {
|
|
18
18
|
const chromeConfig = options.chrome || {};
|
|
19
19
|
|
|
20
20
|
if (!hasConfiguredChromeDriverService) {
|
|
@@ -5,7 +5,7 @@ const getViewPort = require('../../support/getViewPort');
|
|
|
5
5
|
const util = require('../../support/util');
|
|
6
6
|
const log = require('intel').getLogger('browsertime.chrome');
|
|
7
7
|
|
|
8
|
-
module.exports = function(seleniumOptions, browserOptions, options, baseDir) {
|
|
8
|
+
module.exports = function (seleniumOptions, browserOptions, options, baseDir) {
|
|
9
9
|
// Fixing save password popup, only on Desktop
|
|
10
10
|
if (!options.android) {
|
|
11
11
|
seleniumOptions.setUserPreferences({
|
|
@@ -109,10 +109,15 @@ module.exports = function(seleniumOptions, browserOptions, options, baseDir) {
|
|
|
109
109
|
'--remote-debugging-port=' + options.devToolsPort
|
|
110
110
|
);
|
|
111
111
|
} else {
|
|
112
|
-
|
|
112
|
+
if (!browserOptions.noDefaultOptions) {
|
|
113
|
+
seleniumOptions.addArguments(defaultChromeOptions);
|
|
114
|
+
} else {
|
|
115
|
+
log.info('Skip setting default options for Chrome');
|
|
116
|
+
}
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
if (browserOptions.args) {
|
|
120
|
+
log.debug('Set Chrome args %j', browserOptions.args);
|
|
116
121
|
seleniumOptions.addArguments(browserOptions.args);
|
|
117
122
|
}
|
|
118
123
|
|
|
@@ -104,7 +104,7 @@ const legacyProfiles = {
|
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
module.exports = {
|
|
107
|
-
parseTrafficShapeConfig: function(options) {
|
|
107
|
+
parseTrafficShapeConfig: function (options) {
|
|
108
108
|
if (options.connectivity && options.connectivity.profile === 'custom') {
|
|
109
109
|
return {
|
|
110
110
|
down: options.connectivity.down,
|
|
@@ -133,7 +133,7 @@ module.exports = {
|
|
|
133
133
|
return null;
|
|
134
134
|
}
|
|
135
135
|
},
|
|
136
|
-
getProfiles: function() {
|
|
136
|
+
getProfiles: function () {
|
|
137
137
|
return newProfiles;
|
|
138
138
|
}
|
|
139
139
|
};
|
|
@@ -14,7 +14,7 @@ const TS_PROXY_SCRIPT_PATH = path.join(
|
|
|
14
14
|
);
|
|
15
15
|
|
|
16
16
|
function getStartupCriteriaListener(resolve, reject) {
|
|
17
|
-
return function(data) {
|
|
17
|
+
return function (data) {
|
|
18
18
|
const logLine = data.toString();
|
|
19
19
|
if (logLine.startsWith('Started Socks5 proxy server on')) {
|
|
20
20
|
log.debug('Started TSproxy');
|
|
@@ -65,12 +65,12 @@ class TSProxy {
|
|
|
65
65
|
const tsProxyProcess = this.tsProxyProcess;
|
|
66
66
|
|
|
67
67
|
if (this.logVerbose) {
|
|
68
|
-
tsProxyProcess.stderr.on('data', function(data) {
|
|
68
|
+
tsProxyProcess.stderr.on('data', function (data) {
|
|
69
69
|
log.verbose(data.toString().trim());
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
return new Promise(function(resolve, reject) {
|
|
73
|
+
return new Promise(function (resolve, reject) {
|
|
74
74
|
tsProxyProcess.stdout.on(
|
|
75
75
|
'data',
|
|
76
76
|
getStartupCriteriaListener(resolve, reject)
|
|
@@ -96,6 +96,13 @@ class Measure {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
async _stopVideo(url) {
|
|
100
|
+
if (this.recordVideo && !this.options.videoParams.debug) {
|
|
101
|
+
await this.video.stop(url);
|
|
102
|
+
this.videos.push(this.video);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
99
106
|
_error(message) {
|
|
100
107
|
// If we already are measuring a page, associate the error woth that page
|
|
101
108
|
if (this.areWeMeasuring === true) {
|
|
@@ -223,6 +230,9 @@ class Measure {
|
|
|
223
230
|
this.numberOfMeasuredPages++;
|
|
224
231
|
this.numberOfVisitedPages++;
|
|
225
232
|
this.engineDelegate.failing(url);
|
|
233
|
+
// If we got an error we still should stop the video to make sure we can use it to
|
|
234
|
+
// try to understand what went wrong
|
|
235
|
+
await this._stopVideo(url);
|
|
226
236
|
throw e;
|
|
227
237
|
}
|
|
228
238
|
} else {
|
|
@@ -261,14 +271,12 @@ class Measure {
|
|
|
261
271
|
// we also need to add that to the meta data so that the correct folder is created
|
|
262
272
|
if (this.result[this.numberOfMeasuredPages].alias) {
|
|
263
273
|
if (this.options.urlMetaData) {
|
|
264
|
-
this.options.urlMetaData[url] =
|
|
265
|
-
this.numberOfMeasuredPages
|
|
266
|
-
].alias;
|
|
274
|
+
this.options.urlMetaData[url] =
|
|
275
|
+
this.result[this.numberOfMeasuredPages].alias;
|
|
267
276
|
} else {
|
|
268
277
|
this.options.urlMetaData = {};
|
|
269
|
-
this.options.urlMetaData[url] =
|
|
270
|
-
this.numberOfMeasuredPages
|
|
271
|
-
].alias;
|
|
278
|
+
this.options.urlMetaData[url] =
|
|
279
|
+
this.result[this.numberOfMeasuredPages].alias;
|
|
272
280
|
}
|
|
273
281
|
}
|
|
274
282
|
|
|
@@ -276,10 +284,8 @@ class Measure {
|
|
|
276
284
|
await this.storageManager.createSubDataDir(
|
|
277
285
|
path.join(pathToFolder(url, this.options))
|
|
278
286
|
);
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
this.videos.push(this.video);
|
|
282
|
-
}
|
|
287
|
+
await this._stopVideo(url);
|
|
288
|
+
|
|
283
289
|
const alias = this.options.urlMetaData
|
|
284
290
|
? this.options.urlMetaData[url]
|
|
285
291
|
: undefined || this.result[this.numberOfMeasuredPages].alias;
|
|
@@ -18,10 +18,7 @@ class ClickAndHold {
|
|
|
18
18
|
async byXpath(xpath) {
|
|
19
19
|
try {
|
|
20
20
|
const element = await this.driver.findElement(webdriver.By.xpath(xpath));
|
|
21
|
-
return this.actions
|
|
22
|
-
.move({ origin: element })
|
|
23
|
-
.press()
|
|
24
|
-
.perform();
|
|
21
|
+
return this.actions.move({ origin: element }).press().perform();
|
|
25
22
|
} catch (e) {
|
|
26
23
|
log.error('Could not click and hold on element with xpath %s', xpath);
|
|
27
24
|
log.verbose(e);
|
|
@@ -38,10 +35,7 @@ class ClickAndHold {
|
|
|
38
35
|
async bySelector(selector) {
|
|
39
36
|
try {
|
|
40
37
|
const element = await this.driver.findElement(webdriver.By.css(selector));
|
|
41
|
-
return this.actions
|
|
42
|
-
.move({ origin: element })
|
|
43
|
-
.press()
|
|
44
|
-
.perform();
|
|
38
|
+
return this.actions.move({ origin: element }).press().perform();
|
|
45
39
|
} catch (e) {
|
|
46
40
|
log.error(
|
|
47
41
|
'Could not click and hold on element with selector %s',
|
|
@@ -103,10 +97,7 @@ class ClickAndHold {
|
|
|
103
97
|
async releaseAtXpath(xpath) {
|
|
104
98
|
try {
|
|
105
99
|
const element = await this.driver.findElement(webdriver.By.xpath(xpath));
|
|
106
|
-
return this.actions
|
|
107
|
-
.move({ origin: element })
|
|
108
|
-
.release()
|
|
109
|
-
.perform();
|
|
100
|
+
return this.actions.move({ origin: element }).release().perform();
|
|
110
101
|
} catch (e) {
|
|
111
102
|
log.error('Could not release on xpath %s', xpath);
|
|
112
103
|
log.verbose(e);
|
|
@@ -123,10 +114,7 @@ class ClickAndHold {
|
|
|
123
114
|
async releaseAtSelector(selector) {
|
|
124
115
|
try {
|
|
125
116
|
const element = await this.driver.findElement(webdriver.By.css(selector));
|
|
126
|
-
return this.actions
|
|
127
|
-
.move({ origin: element })
|
|
128
|
-
.release()
|
|
129
|
-
.perform();
|
|
117
|
+
return this.actions.move({ origin: element }).release().perform();
|
|
130
118
|
} catch (e) {
|
|
131
119
|
log.error('Could not release on selector %s', selector);
|
|
132
120
|
log.verbose(e);
|
|
@@ -58,10 +58,7 @@ class Switch {
|
|
|
58
58
|
*/
|
|
59
59
|
async toNewTab(url) {
|
|
60
60
|
try {
|
|
61
|
-
await this.browser
|
|
62
|
-
.getDriver()
|
|
63
|
-
.switchTo()
|
|
64
|
-
.newWindow('tab');
|
|
61
|
+
await this.browser.getDriver().switchTo().newWindow('tab');
|
|
65
62
|
if (url) {
|
|
66
63
|
await this.navigate(url);
|
|
67
64
|
await this.browser.extraWait(this.pageCompleteCheck);
|
|
@@ -80,10 +77,7 @@ class Switch {
|
|
|
80
77
|
*/
|
|
81
78
|
async toNewWindow(url) {
|
|
82
79
|
try {
|
|
83
|
-
await this.browser
|
|
84
|
-
.getDriver()
|
|
85
|
-
.switchTo()
|
|
86
|
-
.newWindow('window');
|
|
80
|
+
await this.browser.getDriver().switchTo().newWindow('window');
|
|
87
81
|
if (url) {
|
|
88
82
|
await this.navigate(url);
|
|
89
83
|
await this.browser.extraWait(this.pageCompleteCheck);
|
|
@@ -262,11 +262,10 @@ class Iteration {
|
|
|
262
262
|
'PerceptualSpeedIndexProgress'
|
|
263
263
|
]) {
|
|
264
264
|
if (videoMetrics.visualMetrics[progress]) {
|
|
265
|
-
videoMetrics.visualMetrics[
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
);
|
|
265
|
+
videoMetrics.visualMetrics[progress] =
|
|
266
|
+
util.jsonifyVisualProgress(
|
|
267
|
+
videoMetrics.visualMetrics[progress]
|
|
268
|
+
);
|
|
270
269
|
}
|
|
271
270
|
}
|
|
272
271
|
result[i].videoRecordingStart = videoMetrics.videoRecordingStart;
|
package/lib/core/engine/run.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
module.exports = function(urlOrFunctions) {
|
|
4
|
-
return async function(context, commands) {
|
|
3
|
+
module.exports = function (urlOrFunctions) {
|
|
4
|
+
return async function (context, commands) {
|
|
5
5
|
for (let urlOrFunction of urlOrFunctions) {
|
|
6
6
|
if (typeof urlOrFunction === 'function') {
|
|
7
7
|
await urlOrFunction(context, commands);
|
|
@@ -70,8 +70,9 @@ class SeleniumRunner {
|
|
|
70
70
|
this.driver = await timeout(
|
|
71
71
|
builder.createWebDriver(this.baseDir, this.options),
|
|
72
72
|
this.options.timeouts.browserStart,
|
|
73
|
-
`Failed to start ${this.options.browser} in ${
|
|
74
|
-
.browserStart / 1000
|
|
73
|
+
`Failed to start ${this.options.browser} in ${
|
|
74
|
+
this.options.timeouts.browserStart / 1000
|
|
75
|
+
} seconds.`
|
|
75
76
|
);
|
|
76
77
|
break;
|
|
77
78
|
} catch (e) {
|
|
@@ -85,9 +86,9 @@ class SeleniumRunner {
|
|
|
85
86
|
throw e;
|
|
86
87
|
} else {
|
|
87
88
|
log.info(
|
|
88
|
-
`${this.options.browser} failed to start, trying ${
|
|
89
|
-
i -
|
|
90
|
-
|
|
89
|
+
`${this.options.browser} failed to start, trying ${
|
|
90
|
+
tries - i - 1
|
|
91
|
+
} more time(s): ${e.message}`
|
|
91
92
|
);
|
|
92
93
|
}
|
|
93
94
|
}
|
|
@@ -167,11 +168,13 @@ class SeleniumRunner {
|
|
|
167
168
|
try {
|
|
168
169
|
const pageCompleteCheckCondition = new Condition(
|
|
169
170
|
'for page complete check script to return true',
|
|
170
|
-
function(d) {
|
|
171
|
-
return d
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
function (d) {
|
|
172
|
+
return d
|
|
173
|
+
.executeScript(pageCompleteCheck, waitTime)
|
|
174
|
+
.then(function (t) {
|
|
175
|
+
log.verbose('PageCompleteCheck returned %s', t);
|
|
176
|
+
return t === true;
|
|
177
|
+
});
|
|
175
178
|
}
|
|
176
179
|
);
|
|
177
180
|
log.debug(
|
|
@@ -297,9 +300,9 @@ class SeleniumRunner {
|
|
|
297
300
|
log.info(
|
|
298
301
|
`URL ${url} failed to load, the ${
|
|
299
302
|
this.options.browser
|
|
300
|
-
} are still on ${startURI} , trying ${
|
|
301
|
-
i -
|
|
302
|
-
|
|
303
|
+
} are still on ${startURI} , trying ${
|
|
304
|
+
tries - i - 1
|
|
305
|
+
} more time(s) but first wait for ${waitTime} ms.`
|
|
303
306
|
);
|
|
304
307
|
|
|
305
308
|
if (i === tries - 1) {
|
|
@@ -476,13 +479,11 @@ class SeleniumRunner {
|
|
|
476
479
|
*/
|
|
477
480
|
async getLogs(logType) {
|
|
478
481
|
return timeout(
|
|
479
|
-
this.driver
|
|
480
|
-
.manage()
|
|
481
|
-
.logs()
|
|
482
|
-
.get(logType),
|
|
482
|
+
this.driver.manage().logs().get(logType),
|
|
483
483
|
this.options.timeouts.logs,
|
|
484
|
-
`Extracting logs from ${this.options.browser} took more than ${
|
|
485
|
-
.options.timeouts.logs / 1000
|
|
484
|
+
`Extracting logs from ${this.options.browser} took more than ${
|
|
485
|
+
this.options.timeouts.logs / 1000
|
|
486
|
+
} seconds.`
|
|
486
487
|
);
|
|
487
488
|
}
|
|
488
489
|
|
|
@@ -626,9 +627,9 @@ class SeleniumRunner {
|
|
|
626
627
|
if (!script) {
|
|
627
628
|
let func = category[scriptName].function;
|
|
628
629
|
if (!func) {
|
|
629
|
-
throw
|
|
630
|
-
scriptName +
|
|
631
|
-
|
|
630
|
+
throw (
|
|
631
|
+
'Function and script cannot both be null in ' + scriptName + '.'
|
|
632
|
+
);
|
|
632
633
|
}
|
|
633
634
|
// We wrap the source code of the function in parenthesis
|
|
634
635
|
// "(...)" to contain it in a separate scope. We add a
|
|
@@ -13,7 +13,7 @@ const safari = require('../../safari/webdriver/builder');
|
|
|
13
13
|
* @returns {!Promise<webdriver.WebDriver>} a promise that resolves to the webdriver,
|
|
14
14
|
* or rejects if the current configuration is invalid.
|
|
15
15
|
*/
|
|
16
|
-
module.exports.createWebDriver = async function(baseDir, options) {
|
|
16
|
+
module.exports.createWebDriver = async function (baseDir, options) {
|
|
17
17
|
const browser = options.browser || 'chrome';
|
|
18
18
|
const seleniumUrl = options.selenium ? options.selenium.url : undefined;
|
|
19
19
|
const capabilities = options.selenium
|
|
@@ -7,7 +7,7 @@ const isEmpty = require('lodash.isempty');
|
|
|
7
7
|
const webdriver = require('selenium-webdriver');
|
|
8
8
|
const setupChromiumOptions = require('../../chrome/webdriver/setupChromiumOptions');
|
|
9
9
|
|
|
10
|
-
module.exports.configureBuilder = function(builder, baseDir, options) {
|
|
10
|
+
module.exports.configureBuilder = function (builder, baseDir, options) {
|
|
11
11
|
const edgeConfig = options.edge || {};
|
|
12
12
|
const chromeConfig = options.chrome || {};
|
|
13
13
|
|
|
@@ -46,7 +46,7 @@ function generateURL(port, testUrl, options) {
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
module.exports = async function(url, browser, port, options) {
|
|
49
|
+
module.exports = async function (url, browser, port, options) {
|
|
50
50
|
const configUrl = generateURL(port, url, options);
|
|
51
51
|
log.debug('Configuring browser plugin via %s', configUrl);
|
|
52
52
|
await browser.loadAndWait(configUrl);
|
|
@@ -40,9 +40,8 @@ class GeckoProfiler {
|
|
|
40
40
|
const runner = this.runner;
|
|
41
41
|
const firefoxConfig = this.firefoxConfig;
|
|
42
42
|
const options = this.options;
|
|
43
|
-
const chosenFeatures =
|
|
44
|
-
','
|
|
45
|
-
);
|
|
43
|
+
const chosenFeatures =
|
|
44
|
+
firefoxConfig.geckoProfilerParams.features.split(',');
|
|
46
45
|
const featureString = '["' + chosenFeatures.join('","') + '"]';
|
|
47
46
|
|
|
48
47
|
const chosenThreads = firefoxConfig.geckoProfilerParams.threads.split(',');
|
|
@@ -104,11 +103,13 @@ class GeckoProfiler {
|
|
|
104
103
|
|
|
105
104
|
let deviceProfileFilename = destinationFilename;
|
|
106
105
|
if (isAndroidConfigured(options)) {
|
|
107
|
-
deviceProfileFilename = `/sdcard/geckoProfile-${index}.json`;
|
|
106
|
+
deviceProfileFilename = `/sdcard/Android/data/${this.firefoxConfig.android.package}/files/geckoProfile-${index}.json`;
|
|
108
107
|
}
|
|
109
108
|
|
|
110
109
|
// Must use String.raw or else the backslashes on Windows will be escapes.
|
|
111
|
-
log.info(
|
|
110
|
+
log.info(
|
|
111
|
+
`Collecting Gecko profile from ${deviceProfileFilename} to ${destinationFilename}`
|
|
112
|
+
);
|
|
112
113
|
const script = `
|
|
113
114
|
var callback = arguments[arguments.length - 1];
|
|
114
115
|
Services.profiler.dumpProfileToFileAsync(String.raw\`${deviceProfileFilename}\`)
|
package/lib/firefox/getHAR.js
CHANGED
|
@@ -4,7 +4,7 @@ const log = require('intel').getLogger('browsertime.firefox');
|
|
|
4
4
|
|
|
5
5
|
// Get the HAR from Firefox
|
|
6
6
|
// Using https://github.com/firefox-devtools/har-export-trigger
|
|
7
|
-
module.exports = async function(runner, includeResponseBodies) {
|
|
7
|
+
module.exports = async function (runner, includeResponseBodies) {
|
|
8
8
|
const script = `
|
|
9
9
|
const callback = arguments[arguments.length - 1];
|
|
10
10
|
async function triggerExport() {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
const log = require('intel').getLogger('browsertime.firefox');
|
|
2
3
|
const path = require('path');
|
|
3
4
|
const pathToFolder = require('../support/pathToFolder');
|
|
4
5
|
const { BrowserError } = require('../support/errors');
|
|
@@ -76,7 +77,7 @@ class MemoryReport {
|
|
|
76
77
|
|
|
77
78
|
let deviceReportFilename = destinationFilename;
|
|
78
79
|
if (isAndroidConfigured(options)) {
|
|
79
|
-
deviceReportFilename = `/sdcard/memoryReport-${index}.json`;
|
|
80
|
+
deviceReportFilename = `/sdcard/Android/data/${firefoxConfig.android.package}/files/memoryReport-${index}.json`;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
let minimizeFirst = 'false';
|
|
@@ -84,6 +85,9 @@ class MemoryReport {
|
|
|
84
85
|
minimizeFirst = 'true';
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
log.info(
|
|
89
|
+
`Collecting memory report from ${deviceReportFilename} to ${destinationFilename}`
|
|
90
|
+
);
|
|
87
91
|
let script = `Cc['@mozilla.org/memory-info-dumper;1'].getService(Ci.nsIMemoryInfoDumper).dumpMemoryReportsToNamedFile(String.raw\`${deviceReportFilename}\`, null, null, false, ${minimizeFirst});`;
|
|
88
92
|
await timeout(
|
|
89
93
|
runner.runPrivilegedScript(script, 'Collecting memory report'),
|
|
@@ -13,7 +13,7 @@ const disableTrackingProtectionPreferences = require('../settings/disableTrackin
|
|
|
13
13
|
const util = require('../../support/util');
|
|
14
14
|
const { Android } = require('../../android');
|
|
15
15
|
|
|
16
|
-
module.exports.configureBuilder = function(builder, baseDir, options) {
|
|
16
|
+
module.exports.configureBuilder = function (builder, baseDir, options) {
|
|
17
17
|
// Here we configure everything that we need to start Firefox
|
|
18
18
|
const firefoxConfig = options.firefox || {};
|
|
19
19
|
const moduleRootPath = path.resolve(__dirname, '..', '..', '..');
|
|
@@ -83,18 +83,22 @@ module.exports.configureBuilder = function(builder, baseDir, options) {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
if (!firefoxConfig.noDefaultPrefs) {
|
|
87
|
+
Object.keys(defaultFirefoxPreferences).forEach(function (pref) {
|
|
88
|
+
ffOptions.setPreference(pref, defaultFirefoxPreferences[pref]);
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
log.info('Skip setting default preferences for Firefox');
|
|
92
|
+
}
|
|
89
93
|
|
|
90
94
|
if (firefoxConfig.disableSafeBrowsing) {
|
|
91
|
-
Object.keys(disableSafeBrowsingPreferences).forEach(function(pref) {
|
|
95
|
+
Object.keys(disableSafeBrowsingPreferences).forEach(function (pref) {
|
|
92
96
|
ffOptions.setPreference(pref, disableSafeBrowsingPreferences[pref]);
|
|
93
97
|
});
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
if (firefoxConfig.disableTrackingProtection) {
|
|
97
|
-
Object.keys(disableTrackingProtectionPreferences).forEach(function(pref) {
|
|
101
|
+
Object.keys(disableTrackingProtectionPreferences).forEach(function (pref) {
|
|
98
102
|
ffOptions.setPreference(pref, disableTrackingProtectionPreferences[pref]);
|
|
99
103
|
});
|
|
100
104
|
}
|
|
@@ -140,6 +144,7 @@ module.exports.configureBuilder = function(builder, baseDir, options) {
|
|
|
140
144
|
ffOptions.setPreference('devtools.chrome.enabled', true);
|
|
141
145
|
|
|
142
146
|
const userPrefs = util.toArray(firefoxConfig.preference);
|
|
147
|
+
log.debug('Set Firefox preference %j', userPrefs);
|
|
143
148
|
for (const pref of userPrefs) {
|
|
144
149
|
const name = pref.substr(0, pref.indexOf(':'));
|
|
145
150
|
let value = pref.substr(pref.indexOf(':') + 1);
|
|
@@ -163,7 +168,7 @@ module.exports.configureBuilder = function(builder, baseDir, options) {
|
|
|
163
168
|
get(firefoxConfig, 'developer') ? firefox.Channel.AURORA : undefined
|
|
164
169
|
];
|
|
165
170
|
|
|
166
|
-
firefoxTypes = firefoxTypes.filter(function(n) {
|
|
171
|
+
firefoxTypes = firefoxTypes.filter(function (n) {
|
|
167
172
|
return n !== undefined;
|
|
168
173
|
});
|
|
169
174
|
|
|
@@ -206,13 +206,12 @@ class Firefox {
|
|
|
206
206
|
]) {
|
|
207
207
|
// You can configure to not use content and perceptual.
|
|
208
208
|
if (results[i].visualMetrics[progress]) {
|
|
209
|
-
results[i].visualMetrics[
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
);
|
|
209
|
+
results[i].visualMetrics[progress] =
|
|
210
|
+
util.adjustVisualProgressTimestamps(
|
|
211
|
+
results[i].visualMetrics[progress],
|
|
212
|
+
geckoProfile.meta.startTime,
|
|
213
|
+
firstFrameStartTime
|
|
214
|
+
);
|
|
216
215
|
}
|
|
217
216
|
}
|
|
218
217
|
geckoProfile.meta.visualMetrics = results[i].visualMetrics;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const s = require('selenium-webdriver/safari');
|
|
3
3
|
|
|
4
|
-
module.exports.configureBuilder = async function(builder, baseDir, options) {
|
|
4
|
+
module.exports.configureBuilder = async function (builder, baseDir, options) {
|
|
5
5
|
const safariOptions = options.safari || {};
|
|
6
6
|
builder
|
|
7
7
|
.getCapabilities()
|
|
@@ -80,7 +80,7 @@ function generateScriptObject(name, path, contents) {
|
|
|
80
80
|
content: null,
|
|
81
81
|
isAsync:
|
|
82
82
|
Object.getPrototypeOf(scriptAndMetadataObject.function) ===
|
|
83
|
-
Object.getPrototypeOf(async function() {})
|
|
83
|
+
Object.getPrototypeOf(async function () {})
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
} catch (error) {
|
package/lib/support/cli.js
CHANGED
|
@@ -282,6 +282,12 @@ module.exports.parseCommandLine = function parseCommandLine() {
|
|
|
282
282
|
describe: 'Collect Chromes console log and save to disk.',
|
|
283
283
|
group: 'chrome'
|
|
284
284
|
})
|
|
285
|
+
.option('chrome.noDefaultOptions', {
|
|
286
|
+
type: 'boolean',
|
|
287
|
+
describe:
|
|
288
|
+
'Prevent Browsertime from setting its default options for Chrome',
|
|
289
|
+
group: 'chrome'
|
|
290
|
+
})
|
|
285
291
|
.option('cpu', {
|
|
286
292
|
type: 'boolean',
|
|
287
293
|
describe:
|
|
@@ -483,6 +489,12 @@ module.exports.parseCommandLine = function parseCommandLine() {
|
|
|
483
489
|
type: 'boolean',
|
|
484
490
|
group: 'firefox'
|
|
485
491
|
})
|
|
492
|
+
.option('firefox.noDefaultPrefs', {
|
|
493
|
+
describe: 'Prevents browsertime from setting its default preferences.',
|
|
494
|
+
default: false,
|
|
495
|
+
type: 'boolean',
|
|
496
|
+
group: 'firefox'
|
|
497
|
+
})
|
|
486
498
|
.option('firefox.disableSafeBrowsing', {
|
|
487
499
|
describe: 'Disable safebrowsing.',
|
|
488
500
|
default: true,
|
|
@@ -4,7 +4,7 @@ const path = require('path');
|
|
|
4
4
|
const dayjs = require('dayjs');
|
|
5
5
|
const util = require('../support/util');
|
|
6
6
|
const log = require('intel').getLogger('browsertime');
|
|
7
|
-
const AsyncFunction = Object.getPrototypeOf(async function() {}).constructor;
|
|
7
|
+
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
|
|
8
8
|
|
|
9
9
|
module.exports = {
|
|
10
10
|
loadPrePostScripts(scripts) {
|
|
@@ -25,7 +25,7 @@ const sizeMap = {
|
|
|
25
25
|
'iPad Pro': '1024x1366'
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
module.exports = function(options) {
|
|
28
|
+
module.exports = function (options) {
|
|
29
29
|
// you cannot set the width/height for phone so just keep the viewport undefined
|
|
30
30
|
if (isAndroidConfigured(options)) {
|
|
31
31
|
return;
|
package/lib/support/har/index.js
CHANGED
|
@@ -97,20 +97,19 @@ function addMetaToHAR(index, harPage, url, browserScript, options) {
|
|
|
97
97
|
? options.resultURL
|
|
98
98
|
: options.resultURL + '/';
|
|
99
99
|
if (options.screenshot) {
|
|
100
|
-
_meta.screenshot = `${base}${pathToFolder(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
)}screenshots/${index + 1}/afterPageCompleteCheck.${
|
|
104
|
-
options.screenshotParams.type
|
|
105
|
-
}`;
|
|
100
|
+
_meta.screenshot = `${base}${pathToFolder(url, options)}screenshots/${
|
|
101
|
+
index + 1
|
|
102
|
+
}/afterPageCompleteCheck.${options.screenshotParams.type}`;
|
|
106
103
|
}
|
|
107
104
|
if (options.video) {
|
|
108
|
-
_meta.video = `${base}${pathToFolder(url, options)}video/${
|
|
109
|
-
1
|
|
105
|
+
_meta.video = `${base}${pathToFolder(url, options)}video/${
|
|
106
|
+
index + 1
|
|
107
|
+
}.mp4`;
|
|
110
108
|
}
|
|
111
109
|
if (options.chrome && options.chrome.timeline) {
|
|
112
|
-
_meta.timeline = `${base}${pathToFolder(url, options)}trace-${
|
|
113
|
-
1
|
|
110
|
+
_meta.timeline = `${base}${pathToFolder(url, options)}trace-${
|
|
111
|
+
index + 1
|
|
112
|
+
}.json.gz`;
|
|
114
113
|
}
|
|
115
114
|
}
|
|
116
115
|
if (browserScript && browserScript.pageinfo) {
|
|
@@ -129,7 +128,7 @@ function jsonifyVisualProgress(visualProgress) {
|
|
|
129
128
|
}
|
|
130
129
|
|
|
131
130
|
module.exports = {
|
|
132
|
-
addBrowser: function(har, name, version, comment) {
|
|
131
|
+
addBrowser: function (har, name, version, comment) {
|
|
133
132
|
merge(har.log, {
|
|
134
133
|
browser: {
|
|
135
134
|
name,
|
|
@@ -145,7 +144,7 @@ module.exports = {
|
|
|
145
144
|
return har;
|
|
146
145
|
},
|
|
147
146
|
|
|
148
|
-
addCreator: function(har, comment) {
|
|
147
|
+
addCreator: function (har, comment) {
|
|
149
148
|
merge(har.log, {
|
|
150
149
|
creator: {
|
|
151
150
|
name: 'Browsertime',
|
|
@@ -161,7 +160,7 @@ module.exports = {
|
|
|
161
160
|
return har;
|
|
162
161
|
},
|
|
163
162
|
|
|
164
|
-
getFullyLoaded: function(har) {
|
|
163
|
+
getFullyLoaded: function (har) {
|
|
165
164
|
const fullyLoaded = [];
|
|
166
165
|
const entries = Array.from(har.log.entries);
|
|
167
166
|
|
|
@@ -190,7 +189,7 @@ module.exports = {
|
|
|
190
189
|
return fullyLoaded;
|
|
191
190
|
},
|
|
192
191
|
|
|
193
|
-
mergeHars: function(hars) {
|
|
192
|
+
mergeHars: function (hars) {
|
|
194
193
|
if (isEmpty(hars)) {
|
|
195
194
|
return undefined;
|
|
196
195
|
}
|
|
@@ -10,7 +10,7 @@ function toSafeKey(key) {
|
|
|
10
10
|
return key.replace(/[.~ /+|,:?&%–)(]|%7C/g, '-');
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
module.exports = function(url, options) {
|
|
13
|
+
module.exports = function (url, options) {
|
|
14
14
|
if (options.useSameDir) {
|
|
15
15
|
return '';
|
|
16
16
|
} else {
|
|
@@ -31,19 +31,13 @@ module.exports = function(url, options) {
|
|
|
31
31
|
|
|
32
32
|
if (useHash && !isEmpty(parsedUrl.hash)) {
|
|
33
33
|
const md5 = crypto.createHash('md5'),
|
|
34
|
-
hash = md5
|
|
35
|
-
.update(parsedUrl.hash)
|
|
36
|
-
.digest('hex')
|
|
37
|
-
.substring(0, 8);
|
|
34
|
+
hash = md5.update(parsedUrl.hash).digest('hex').substring(0, 8);
|
|
38
35
|
urlSegments.push('hash-' + hash);
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
if (!isEmpty(parsedUrl.search)) {
|
|
42
39
|
const md5 = crypto.createHash('md5'),
|
|
43
|
-
hash = md5
|
|
44
|
-
.update(parsedUrl.search)
|
|
45
|
-
.digest('hex')
|
|
46
|
-
.substring(0, 8);
|
|
40
|
+
hash = md5.update(parsedUrl.search).digest('hex').substring(0, 8);
|
|
47
41
|
urlSegments.push('query-' + hash);
|
|
48
42
|
}
|
|
49
43
|
|
|
@@ -65,7 +59,7 @@ module.exports = function(url, options) {
|
|
|
65
59
|
|
|
66
60
|
pathSegments.push('data');
|
|
67
61
|
|
|
68
|
-
pathSegments.forEach(function(segment, index) {
|
|
62
|
+
pathSegments.forEach(function (segment, index) {
|
|
69
63
|
if (segment) {
|
|
70
64
|
pathSegments[index] = segment.replace(
|
|
71
65
|
/[^-a-z0-9_.\u0621-\u064A]/gi,
|
package/lib/support/preURL.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const log = require('intel').getLogger('browsertime');
|
|
4
4
|
const delay = ms => new Promise(res => setTimeout(res, ms));
|
|
5
5
|
|
|
6
|
-
module.exports = async function(browser, options) {
|
|
6
|
+
module.exports = async function (browser, options) {
|
|
7
7
|
log.info('Accessing preURL %s', options.preURL);
|
|
8
8
|
await browser.loadAndWait(options.preURL);
|
|
9
9
|
await delay(options.preURLDelay ? options.preURLDelay : 1500);
|
|
@@ -137,7 +137,7 @@ class Statistics {
|
|
|
137
137
|
stats.stddev() / Math.sqrt(stats.length).toFixed(decimals)
|
|
138
138
|
) // "standard deviation of the mean"
|
|
139
139
|
};
|
|
140
|
-
percentiles.forEach(function(p) {
|
|
140
|
+
percentiles.forEach(function (p) {
|
|
141
141
|
let name = percentileName(p);
|
|
142
142
|
node[name] = parseFloat(stats.percentile(p).toFixed(decimals));
|
|
143
143
|
});
|
package/lib/support/stop.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const execa = require('execa');
|
|
4
4
|
const log = require('intel').getLogger('browsertime');
|
|
5
5
|
|
|
6
|
-
module.exports = async function(processName) {
|
|
6
|
+
module.exports = async function (processName) {
|
|
7
7
|
const scriptArgs = ['-9', processName];
|
|
8
8
|
|
|
9
9
|
log.debug('Kill all processes ' + processName);
|
|
@@ -17,9 +17,7 @@ const unlink = promisify(fs.unlink);
|
|
|
17
17
|
const mkdir = promisify(fs.mkdir);
|
|
18
18
|
|
|
19
19
|
const defaultDir = 'browsertime-results';
|
|
20
|
-
let timestamp = dayjs()
|
|
21
|
-
.format()
|
|
22
|
-
.replace(/:/g, '');
|
|
20
|
+
let timestamp = dayjs().format().replace(/:/g, '');
|
|
23
21
|
|
|
24
22
|
function pathNameFromUrl(url) {
|
|
25
23
|
const parsedUrl = urlParser.parse(url),
|
|
@@ -29,10 +27,7 @@ function pathNameFromUrl(url) {
|
|
|
29
27
|
|
|
30
28
|
if (!isEmpty(parsedUrl.search)) {
|
|
31
29
|
const md5 = crypto.createHash('md5'),
|
|
32
|
-
hash = md5
|
|
33
|
-
.update(parsedUrl.search)
|
|
34
|
-
.digest('hex')
|
|
35
|
-
.substring(0, 8);
|
|
30
|
+
hash = md5.update(parsedUrl.search).digest('hex').substring(0, 8);
|
|
36
31
|
pathSegments.push('query-' + hash);
|
|
37
32
|
}
|
|
38
33
|
|
|
@@ -115,18 +110,18 @@ class StorageManager {
|
|
|
115
110
|
}
|
|
116
111
|
|
|
117
112
|
async gzip(inputFile, outputFile, removeInput) {
|
|
118
|
-
const promise = new Promise(function(resolve, reject) {
|
|
113
|
+
const promise = new Promise(function (resolve, reject) {
|
|
119
114
|
const gzip = zlib.createGzip();
|
|
120
115
|
const input = fs.createReadStream(inputFile);
|
|
121
116
|
const out = fs.createWriteStream(outputFile);
|
|
122
|
-
out.on('finish', function() {
|
|
117
|
+
out.on('finish', function () {
|
|
123
118
|
if (removeInput) {
|
|
124
119
|
unlink(inputFile).then(() => resolve());
|
|
125
120
|
} else {
|
|
126
121
|
resolve();
|
|
127
122
|
}
|
|
128
123
|
});
|
|
129
|
-
out.on('error', function(e) {
|
|
124
|
+
out.on('error', function (e) {
|
|
130
125
|
log.error('Could not gzip %s to %s', inputFile, outputFile, e);
|
|
131
126
|
reject();
|
|
132
127
|
});
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const execa = require('execa');
|
|
4
4
|
const log = require('intel').getLogger('browsertime.video');
|
|
5
5
|
|
|
6
|
-
module.exports = async function(src, dest, framerate) {
|
|
6
|
+
module.exports = async function (src, dest, framerate) {
|
|
7
7
|
const scriptArgs = ['-nostdin', '-i', src, '-r', framerate, dest];
|
|
8
8
|
log.info('Converting video to %s fps', framerate);
|
|
9
9
|
return execa('ffmpeg', scriptArgs);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
module.exports = function(options) {
|
|
4
|
+
module.exports = function (options) {
|
|
5
5
|
// If the font is not part of the params and we're on macOS
|
|
6
6
|
// we check that SFNSMono.ttf is available
|
|
7
7
|
if (!options.videoParams.fontPath && process.platform === 'darwin') {
|
|
@@ -26,11 +26,12 @@ function get(metric, metricName, pos, options) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// H-h/8
|
|
29
|
-
return `drawtext=${fontFile}enable='between(t,${
|
|
30
|
-
|
|
29
|
+
return `drawtext=${fontFile}enable='between(t,${
|
|
30
|
+
Number(metric) / 1000
|
|
31
|
+
},30)':x=(w-tw)/2: y=H-${pos}-h/${x}:fontcolor=white:fontsize=h/${fontSize}:box=1:boxcolor=0x000000AA:boxborderw=2:text='${metricName} ${metric}'`;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
module.exports = function(videoMetrics, timingMetrics, options) {
|
|
34
|
+
module.exports = function (videoMetrics, timingMetrics, options) {
|
|
34
35
|
let text = '';
|
|
35
36
|
const vm = videoMetrics.visualMetrics;
|
|
36
37
|
const startPosition = 'h/10';
|
|
@@ -59,7 +60,7 @@ module.exports = function(videoMetrics, timingMetrics, options) {
|
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
metricsAndValues.sort(function(a, b) {
|
|
63
|
+
metricsAndValues.sort(function (a, b) {
|
|
63
64
|
return b.value - a.value;
|
|
64
65
|
});
|
|
65
66
|
|
|
@@ -38,9 +38,9 @@ async function buildX11FfmpegArgs({
|
|
|
38
38
|
'-r',
|
|
39
39
|
30,
|
|
40
40
|
'-filter:v',
|
|
41
|
-
`crop=${widthAndHeight[0] * devicePixelRatio}:${
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
`crop=${widthAndHeight[0] * devicePixelRatio}:${
|
|
42
|
+
widthAndHeight[1] * devicePixelRatio
|
|
43
|
+
}:${offset.x * devicePixelRatio}:${offset.y * devicePixelRatio}`,
|
|
44
44
|
'-codec:v',
|
|
45
45
|
'libx264rgb',
|
|
46
46
|
'-threads',
|
|
@@ -81,7 +81,7 @@ function writeFrameDurationsToFile(directoryName, imageFiles) {
|
|
|
81
81
|
const stream = fs.createWriteStream(
|
|
82
82
|
path.join(directoryName, 'durations.txt')
|
|
83
83
|
);
|
|
84
|
-
stream.once('open', function() {
|
|
84
|
+
stream.once('open', function () {
|
|
85
85
|
stream.write(
|
|
86
86
|
"file '" + path.join(directoryName, imageFiles[0].filename) + "'\n"
|
|
87
87
|
);
|
|
@@ -120,7 +120,7 @@ async function generateVideo(destination, recordingDirectoryName) {
|
|
|
120
120
|
imageFiles.push({ filename: newFilename, offset: offset });
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
-
imageFiles.sort(function(a, b) {
|
|
123
|
+
imageFiles.sort(function (a, b) {
|
|
124
124
|
if (a.filename < b.filename) return -1;
|
|
125
125
|
if (a.filename > b.filename) return 1;
|
|
126
126
|
return 0;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const log = require('intel').getLogger('browsertime.video');
|
|
4
4
|
const { until, By } = require('selenium-webdriver');
|
|
5
|
-
module.exports = async function(driver, options) {
|
|
5
|
+
module.exports = async function (driver, options) {
|
|
6
6
|
log.debug('Add orange color');
|
|
7
7
|
// We tried other ways for Android (access an orange page)
|
|
8
8
|
// That works fine ... but break scripts
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"description": "Browsertime",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.8.0",
|
|
4
4
|
"bin": "./bin/browsertime.js",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@sitespeed.io/throttle": "3.0.0",
|
|
7
7
|
"@devicefarmer/adbkit": "2.11.3",
|
|
8
8
|
"btoa": "1.2.1",
|
|
9
|
-
"@sitespeed.io/chromedriver": "
|
|
9
|
+
"@sitespeed.io/chromedriver": "95.0.4638-17",
|
|
10
10
|
"chrome-har": "0.11.12",
|
|
11
11
|
"chrome-remote-interface": "0.31.0",
|
|
12
12
|
"dayjs": "1.10.5",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"lodash.merge": "4.6.2",
|
|
23
23
|
"lodash.pick": "4.4.0",
|
|
24
24
|
"lodash.set": "4.3.2",
|
|
25
|
-
"selenium-webdriver": "4.0.0
|
|
26
|
-
"@sitespeed.io/edgedriver": "
|
|
25
|
+
"selenium-webdriver": "4.0.0",
|
|
26
|
+
"@sitespeed.io/edgedriver": "95.0.1020-30",
|
|
27
27
|
"@sitespeed.io/geckodriver": "0.29.1-2",
|
|
28
28
|
"@sitespeed.io/tracium": "0.3.3",
|
|
29
29
|
"speedline-core": "1.4.3",
|
|
@@ -34,15 +34,15 @@
|
|
|
34
34
|
"jimp": "0.16.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"bluebird": "3.
|
|
38
|
-
"chai": "4.
|
|
37
|
+
"bluebird": "3.7.2",
|
|
38
|
+
"chai": "4.3.4",
|
|
39
39
|
"chai-as-promised": "7.1.1",
|
|
40
|
-
"eslint": "
|
|
41
|
-
"eslint-config-prettier": "
|
|
42
|
-
"eslint-plugin-prettier": "
|
|
40
|
+
"eslint": "8.0.1",
|
|
41
|
+
"eslint-config-prettier": "8.3.0",
|
|
42
|
+
"eslint-plugin-prettier": "4.0.0",
|
|
43
43
|
"longjohn": "0.2.12",
|
|
44
44
|
"mocha": "6.2.0",
|
|
45
|
-
"prettier": "
|
|
45
|
+
"prettier": "2.4.1"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=10.13.0"
|