browsertime 14.20.3 → 15.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +5 -5
- package/lib/chrome/webdriver/chromium.js +0 -9
- package/lib/chrome/webdriver/setupChromiumOptions.js +18 -29
- package/lib/connectivity/index.js +0 -9
- package/lib/core/engine/index.js +40 -59
- package/lib/core/engine/iteration.js +6 -1
- package/lib/core/seleniumRunner.js +5 -15
- package/lib/firefox/settings/firefoxPreferences.js +1 -4
- package/lib/firefox/webdriver/builder.js +0 -14
- package/lib/firefox/webdriver/firefox.js +20 -21
- package/lib/support/cli.js +2 -14
- package/lib/support/dns.js +44 -0
- package/package.json +34 -26
- package/browserscripts/browser/appConstants.js +0 -9
- package/browserscripts/browser/asyncAppConstants.js +0 -11
- package/lib/chrome/speedline.js +0 -84
- package/lib/connectivity/tsProxy.js +0 -108
- package/vendor/tsproxy.py +0 -842
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"description": "Browsertime",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "15.0.1",
|
|
4
4
|
"bin": "./bin/browsertime.js",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@
|
|
6
|
+
"@cypress/xvfb": "1.2.4",
|
|
7
7
|
"@devicefarmer/adbkit": "2.11.3",
|
|
8
|
-
"btoa": "1.2.1",
|
|
9
8
|
"@sitespeed.io/chromedriver": "98.0.4758-48b",
|
|
9
|
+
"@sitespeed.io/edgedriver": "98.0.1108-43",
|
|
10
|
+
"@sitespeed.io/geckodriver": "0.30.0",
|
|
11
|
+
"@sitespeed.io/throttle": "3.0.0",
|
|
12
|
+
"@sitespeed.io/tracium": "0.3.3",
|
|
13
|
+
"btoa": "1.2.1",
|
|
10
14
|
"chrome-har": "0.12.0",
|
|
11
15
|
"chrome-remote-interface": "0.31.0",
|
|
12
16
|
"dayjs": "1.10.7",
|
|
@@ -22,27 +26,20 @@
|
|
|
22
26
|
"lodash.merge": "4.6.2",
|
|
23
27
|
"lodash.pick": "4.4.0",
|
|
24
28
|
"lodash.set": "4.3.2",
|
|
25
|
-
"selenium-webdriver": "4.1.
|
|
26
|
-
"@sitespeed.io/edgedriver": "95.0.1020-30",
|
|
27
|
-
"@sitespeed.io/geckodriver": "0.30.0",
|
|
28
|
-
"@sitespeed.io/tracium": "0.3.3",
|
|
29
|
-
"speedline-core": "1.4.3",
|
|
30
|
-
"@cypress/xvfb": "1.2.4",
|
|
29
|
+
"selenium-webdriver": "4.1.1",
|
|
31
30
|
"yargs": "17.2.1"
|
|
32
31
|
},
|
|
33
32
|
"optionalDependencies": {
|
|
34
33
|
"jimp": "0.16.1"
|
|
35
34
|
},
|
|
36
35
|
"devDependencies": {
|
|
37
|
-
"
|
|
38
|
-
"chai": "4.3.4",
|
|
39
|
-
"chai-as-promised": "7.1.1",
|
|
36
|
+
"ava": "4.0.1",
|
|
40
37
|
"eslint": "8.0.1",
|
|
41
38
|
"eslint-config-prettier": "8.3.0",
|
|
42
39
|
"eslint-plugin-prettier": "4.0.0",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
40
|
+
"prettier": "2.4.1",
|
|
41
|
+
"serve-handler": "6.1.3",
|
|
42
|
+
"serve": "13.0.2"
|
|
46
43
|
},
|
|
47
44
|
"engines": {
|
|
48
45
|
"node": ">=10.13.0"
|
|
@@ -65,21 +62,17 @@
|
|
|
65
62
|
],
|
|
66
63
|
"main": "index.js",
|
|
67
64
|
"scripts": {
|
|
68
|
-
"test": "
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"test:selenium": "mocha test/browserTests/seleniumRunnerTests.js",
|
|
72
|
-
"test:commands": "mocha test/commandTests",
|
|
65
|
+
"test": "ava",
|
|
66
|
+
"start-server": "serve test/data/html/",
|
|
67
|
+
"stop-server": "sudo pkill serve",
|
|
73
68
|
"lint": "eslint .",
|
|
74
|
-
"lint:fix": "eslint . --fix"
|
|
75
|
-
"eslint-check": "eslint --print-config .eslintrc.json | eslint-config-prettier-check",
|
|
76
|
-
"travis": "npm run eslint-check && npm run lint && npm run test"
|
|
69
|
+
"lint:fix": "eslint . --fix"
|
|
77
70
|
},
|
|
78
71
|
"name": "browsertime",
|
|
79
|
-
"author": "
|
|
72
|
+
"author": "Peter Hedenskog",
|
|
80
73
|
"contributors": [
|
|
81
74
|
{
|
|
82
|
-
"name": "
|
|
75
|
+
"name": "Tobias Lidskog"
|
|
83
76
|
},
|
|
84
77
|
{
|
|
85
78
|
"name": "Jonathan Lee"
|
|
@@ -90,5 +83,20 @@
|
|
|
90
83
|
"url": "https://github.com/sitespeedio/browsertime.git"
|
|
91
84
|
},
|
|
92
85
|
"homepage": "https://www.sitespeed.io/documentation/browsertime/",
|
|
93
|
-
"license": "MIT"
|
|
86
|
+
"license": "MIT",
|
|
87
|
+
"ava": {
|
|
88
|
+
"files": [
|
|
89
|
+
"test/**/*",
|
|
90
|
+
"!test/util",
|
|
91
|
+
"!test/data"
|
|
92
|
+
],
|
|
93
|
+
"concurrency": 1,
|
|
94
|
+
"failFast": true,
|
|
95
|
+
"require": [
|
|
96
|
+
"./test/util/setup.js"
|
|
97
|
+
],
|
|
98
|
+
"nodeArguments": [
|
|
99
|
+
"--trace-deprecation"
|
|
100
|
+
]
|
|
101
|
+
}
|
|
94
102
|
}
|
package/lib/chrome/speedline.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const speedline = require('speedline-core');
|
|
4
|
-
const log = require('intel').getLogger('browsertime.chrome');
|
|
5
|
-
const visualMetricsExtra = require('../video/postprocessing/visualmetrics/extraMetrics');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const images = require('../support/images');
|
|
8
|
-
|
|
9
|
-
function pad(n) {
|
|
10
|
-
const extraZeroes = 6 - n.toString().length;
|
|
11
|
-
for (let i = 0; i < extraZeroes; i++) {
|
|
12
|
-
n = '0' + n;
|
|
13
|
-
}
|
|
14
|
-
return n;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Use SpeedLine to analyse the Chrome trace log to get Visual Metrics.
|
|
19
|
-
* Not as good as using a video but maybe usable in some cases.
|
|
20
|
-
*/
|
|
21
|
-
module.exports = async function (trace, result, index) {
|
|
22
|
-
try {
|
|
23
|
-
const navStart = trace.traceEvents.filter(
|
|
24
|
-
task =>
|
|
25
|
-
task.cat === 'blink.user_timing' && task.name === 'navigationStart'
|
|
26
|
-
);
|
|
27
|
-
navStart.sort(function (a, b) {
|
|
28
|
-
return a.ts - b.ts;
|
|
29
|
-
});
|
|
30
|
-
log.debug('Get Speedline result from the trace');
|
|
31
|
-
const speedlineResult = await speedline(trace.traceEvents, {
|
|
32
|
-
timeOrigin: navStart[0].ts,
|
|
33
|
-
fastMode: true
|
|
34
|
-
});
|
|
35
|
-
log.debug('Got Speedline result.');
|
|
36
|
-
const startTs = speedlineResult.beginning;
|
|
37
|
-
const visualProgress = speedlineResult.frames
|
|
38
|
-
.map(frame => {
|
|
39
|
-
const ts = Math.floor(frame.getTimeStamp() - startTs);
|
|
40
|
-
return `${ts}=${Math.floor(frame.getProgress())}%`;
|
|
41
|
-
})
|
|
42
|
-
.join(', ');
|
|
43
|
-
|
|
44
|
-
const visualMetrics = visualMetricsExtra({
|
|
45
|
-
FirstVisualChange: Number(speedlineResult.first.toFixed(0)),
|
|
46
|
-
LastVisualChange: Number(speedlineResult.complete.toFixed(0)),
|
|
47
|
-
SpeedIndex: Number(speedlineResult.speedIndex.toFixed(0)),
|
|
48
|
-
PerceptualSpeedIndex: Number(
|
|
49
|
-
speedlineResult.perceptualSpeedIndex.toFixed(0)
|
|
50
|
-
),
|
|
51
|
-
VisualProgress: visualProgress
|
|
52
|
-
}).visualMetrics;
|
|
53
|
-
|
|
54
|
-
const promises = [];
|
|
55
|
-
for (let frame of speedlineResult.frames) {
|
|
56
|
-
// follow the name standard of Visual Metrics
|
|
57
|
-
// ms_000000.jpg
|
|
58
|
-
const d = new Date(frame.getTimeStamp() - startTs);
|
|
59
|
-
const name = 'ms_' + pad(d.getTime());
|
|
60
|
-
promises.push(
|
|
61
|
-
images.saveJpg(
|
|
62
|
-
name,
|
|
63
|
-
frame.getImage(),
|
|
64
|
-
result.url,
|
|
65
|
-
this.storageManager,
|
|
66
|
-
{
|
|
67
|
-
type: 'jpg',
|
|
68
|
-
jpg: {
|
|
69
|
-
quality: 80
|
|
70
|
-
},
|
|
71
|
-
maxSize: 400
|
|
72
|
-
},
|
|
73
|
-
path.join('filmstrip', index + ''),
|
|
74
|
-
this.options
|
|
75
|
-
)
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
await Promise.all(promises);
|
|
80
|
-
return visualMetrics;
|
|
81
|
-
} catch (e) {
|
|
82
|
-
log.error('Could not generate Visual Metrics using SpeedLine', e);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const execa = require('execa');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const get = require('lodash.get');
|
|
6
|
-
const log = require('intel').getLogger('browsertime.connectivity.tsproxy');
|
|
7
|
-
|
|
8
|
-
const TS_PROXY_SCRIPT_PATH = path.join(
|
|
9
|
-
__dirname,
|
|
10
|
-
'..',
|
|
11
|
-
'..',
|
|
12
|
-
'vendor',
|
|
13
|
-
'tsproxy.py'
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
function getStartupCriteriaListener(resolve, reject) {
|
|
17
|
-
return function (data) {
|
|
18
|
-
const logLine = data.toString();
|
|
19
|
-
if (logLine.startsWith('Started Socks5 proxy server on')) {
|
|
20
|
-
log.debug('Started TSproxy');
|
|
21
|
-
return resolve();
|
|
22
|
-
} else if (logLine.startsWith('Unable to listen on')) {
|
|
23
|
-
return reject(new Error('TSProxy process logged: ' + logLine));
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
class TSProxy {
|
|
29
|
-
constructor(options) {
|
|
30
|
-
this.logVerbose = options.verbose >= 2;
|
|
31
|
-
this.port = get(options.connectivity, 'tsproxy.port', 1080);
|
|
32
|
-
this.bind = get(options.connectivity, 'tsproxy.bind');
|
|
33
|
-
this.options = options;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
start(profile) {
|
|
37
|
-
const scriptArgs = [
|
|
38
|
-
TS_PROXY_SCRIPT_PATH,
|
|
39
|
-
'--rtt',
|
|
40
|
-
profile.rtt,
|
|
41
|
-
'--inkbps',
|
|
42
|
-
profile.down,
|
|
43
|
-
'--outkbps',
|
|
44
|
-
profile.up
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
if (this.bind) {
|
|
48
|
-
scriptArgs.push('--bind', this.bind);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (isFinite(this.port)) {
|
|
52
|
-
scriptArgs.push('-p', this.port);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (this.logVerbose) {
|
|
56
|
-
scriptArgs.push('-vvvv');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
log.info('Start TSProxy:' + scriptArgs.join(' '));
|
|
60
|
-
this.tsProxyProcess = execa(
|
|
61
|
-
this.options.docker ? 'python2' : 'python',
|
|
62
|
-
scriptArgs
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
const tsProxyProcess = this.tsProxyProcess;
|
|
66
|
-
|
|
67
|
-
if (this.logVerbose) {
|
|
68
|
-
tsProxyProcess.stderr.on('data', function (data) {
|
|
69
|
-
log.verbose(data.toString().trim());
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return new Promise(function (resolve, reject) {
|
|
74
|
-
tsProxyProcess.stdout.on(
|
|
75
|
-
'data',
|
|
76
|
-
getStartupCriteriaListener(resolve, reject)
|
|
77
|
-
);
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
stop() {
|
|
82
|
-
if (this.tsProxyProcess) {
|
|
83
|
-
this.tsProxyProcess.stdout.removeAllListeners('data');
|
|
84
|
-
this.tsProxyProcess.stderr.removeAllListeners('data');
|
|
85
|
-
|
|
86
|
-
return new Promise((resolve, reject) => {
|
|
87
|
-
this.tsProxyProcess
|
|
88
|
-
.once('exit', () => {
|
|
89
|
-
// guard against exit event sent after error event,
|
|
90
|
-
// see https://nodejs.org/api/child_process.html#child_process_event_error
|
|
91
|
-
if (this.tsProxyProcess) {
|
|
92
|
-
this.tsProxyProcess = null;
|
|
93
|
-
log.debug('Closing TSproxy');
|
|
94
|
-
resolve();
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
-
.once('error', err => {
|
|
98
|
-
this.tsProxyProcess = null;
|
|
99
|
-
reject(err);
|
|
100
|
-
});
|
|
101
|
-
this.tsProxyProcess.kill('SIGINT');
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
return Promise.resolve();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
module.exports = TSProxy;
|