phantomas 2.2.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +32 -29
- package/README.md +13 -2
- package/bin/program.js +8 -0
- package/core/modules/navigationTiming/scope.js +2 -1
- package/core/scope.js +2 -1
- package/extensions/pageSource/pageSource.js +2 -0
- package/extensions/pageStorage/pageStorage.js +82 -0
- package/extensions/scroll/scroll.js +3 -0
- package/hooks/build +1 -1
- package/lib/browser.js +14 -8
- package/lib/index.js +7 -3
- package/lib/metadata/metadata.json +17 -7
- package/modules/ajaxRequests/scope.js +1 -1
- package/modules/analyzeCss/analyzeCss.js +77 -78
- package/modules/analyzeCss/scope.js +1 -1
- package/modules/cacheHits/cacheHits.js +6 -3
- package/modules/documentHeight/scope.js +1 -1
- package/modules/domComplexity/scope.js +1 -1
- package/modules/domHiddenContent/scope.js +1 -1
- package/modules/domMutations/scope.js +1 -1
- package/modules/domQueries/scope.js +1 -1
- package/modules/domains/domains.js +1 -1
- package/modules/events/scope.js +2 -1
- package/modules/globalVariables/scope.js +1 -1
- package/modules/jQuery/scope.js +1 -1
- package/modules/javaScriptBottlenecks/scope.js +1 -1
- package/modules/lazyLoadableImages/scope.js +1 -1
- package/modules/localStorage/scope.js +1 -1
- package/modules/protocols/protocols.js +21 -4
- package/modules/requestsStats/requestsStats.js +1 -1
- package/modules/staticAssets/staticAssets.js +2 -1
- package/modules/windowPerformance/windowPerformance.js +1 -0
- package/package.json +28 -18
- package/lib/fast-stats.js +0 -634
package/Dockerfile
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
# https://hub.docker.com/_/node
|
|
2
|
-
FROM node:lts-
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
2
|
+
FROM node:lts-bullseye-slim
|
|
3
|
+
|
|
4
|
+
# install dependencies of Chrome binary that will be fetched by npm ci
|
|
5
|
+
RUN apt-get update \
|
|
6
|
+
&& apt-get install -y --no-install-recommends \
|
|
7
|
+
fonts-liberation \
|
|
8
|
+
libasound2 \
|
|
9
|
+
libatk-bridge2.0-0 \
|
|
10
|
+
libatk1.0-0 \
|
|
11
|
+
libatspi2.0-0 \
|
|
12
|
+
libc6 \
|
|
13
|
+
libcairo2 \
|
|
14
|
+
libcups2 \
|
|
15
|
+
libdbus-1-3 \
|
|
16
|
+
libfreetype6 \
|
|
17
|
+
libgbm1 \
|
|
18
|
+
libharfbuzz0b \
|
|
19
|
+
libnss3 \
|
|
20
|
+
libpango-1.0-0 \
|
|
21
|
+
libx11-6 \
|
|
22
|
+
libxext6 \
|
|
23
|
+
libxkbcommon0 \
|
|
24
|
+
x11-utils \
|
|
25
|
+
xdg-utils \
|
|
26
|
+
zlib1g \
|
|
27
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
24
28
|
|
|
25
29
|
# Set up a working directory
|
|
26
30
|
ENV HOME /opt/phantomas
|
|
@@ -30,11 +34,6 @@ RUN chown -R nobody:nogroup .
|
|
|
30
34
|
# Run everything after as non-privileged user.
|
|
31
35
|
USER nobody
|
|
32
36
|
|
|
33
|
-
# Tell Puppeteer to skip installing Chrome. We'll be using the installed binary
|
|
34
|
-
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
|
|
35
|
-
|
|
36
|
-
# Tell phantomas where Chromium binary is and that we're in docker
|
|
37
|
-
ENV PHANTOMAS_CHROMIUM_EXECUTABLE /usr/bin/chromium-browser
|
|
38
37
|
ENV DOCKERIZED yes
|
|
39
38
|
|
|
40
39
|
# Install dependencies
|
|
@@ -42,8 +41,12 @@ COPY package.json .
|
|
|
42
41
|
COPY package-lock.json .
|
|
43
42
|
RUN npm ci
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
# TODO: find the chrome binary and symlink it to the PATH
|
|
45
|
+
RUN ldd $(find . -wholename '*chrome-linux/chrome') && \
|
|
46
|
+
$(find . -wholename '*chrome-linux/chrome') --version
|
|
47
|
+
|
|
48
|
+
ARG GITHUB_SHA="dev"
|
|
49
|
+
ENV COMMIT_SHA ${GITHUB_SHA}
|
|
47
50
|
|
|
48
51
|
# label the image with branch name and commit hash
|
|
49
52
|
LABEL maintainer="maciej.brencz@gmail.com"
|
package/README.md
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
phantomas
|
|
1
|
+
phantomas
|
|
2
|
+
[]()
|
|
3
|
+
[](http://inch-ci.org/github/macbre/phantomas)
|
|
4
|
+
[](https://github.com/prettier/prettier)
|
|
5
|
+
[](https://coveralls.io/github/macbre/phantomas?branch=devel)
|
|
6
|
+
[](https://www.codefactor.io/repository/github/macbre/phantomas)
|
|
2
7
|
=========
|
|
3
8
|
|
|
4
9
|
[Headless Chromium](https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md)-based modular web performance metrics collector. And why phantomas? Well, [because](http://en.wikipedia.org/wiki/Fantômas) :)
|
|
5
10
|
|
|
6
11
|
## Requirements
|
|
7
12
|
|
|
8
|
-
* [NodeJS](http://nodejs.org)
|
|
13
|
+
* [NodeJS](http://nodejs.org) 14+
|
|
9
14
|
|
|
10
15
|
## Installation
|
|
11
16
|
|
|
@@ -27,6 +32,12 @@ You can use [phantomas Docker image](https://hub.docker.com/r/macbre/phantomas):
|
|
|
27
32
|
docker pull macbre/phantomas:latest
|
|
28
33
|
```
|
|
29
34
|
|
|
35
|
+
Or you can fetch from [GitHub's Containers registry](https://github.com/macbre/phantomas/pkgs/container/phantomas)
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
docker pull ghcr.io/macbre/phantomas:latest
|
|
39
|
+
```
|
|
40
|
+
|
|
30
41
|
## Support
|
|
31
42
|
|
|
32
43
|
[](https://xscode.com/macbre/phantomas)
|
package/bin/program.js
CHANGED
|
@@ -68,6 +68,14 @@ function getProgram() {
|
|
|
68
68
|
"--cookies-file <file>",
|
|
69
69
|
"specifies the file name to store the persistent Cookies"
|
|
70
70
|
)
|
|
71
|
+
.option(
|
|
72
|
+
"--local-storage <values>",
|
|
73
|
+
'ability to set a local storage, key-value pairs (e.g. "bar=foo;domain=url")'
|
|
74
|
+
)
|
|
75
|
+
.option(
|
|
76
|
+
"--session-storage <values>",
|
|
77
|
+
'ability to set a session storage, key-value pairs (e.g. "bar=foo;domain=url")'
|
|
78
|
+
)
|
|
71
79
|
.option(
|
|
72
80
|
"--ignore-ssl-errors",
|
|
73
81
|
"ignores SSL errors, such as expired or self-signed certificate errors"
|
package/core/scope.js
CHANGED
|
@@ -33,6 +33,8 @@ module.exports = (phantomas) => {
|
|
|
33
33
|
return new Promise(async (resolve) => {
|
|
34
34
|
// https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#pageevaluatepagefunction-args
|
|
35
35
|
const bodyHandle = await page.$("body");
|
|
36
|
+
|
|
37
|
+
/* istanbul ignore next */
|
|
36
38
|
const html = await page.evaluate((body) => body.innerHTML, bodyHandle);
|
|
37
39
|
|
|
38
40
|
// phantomas.log(html);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Support for session-/localStorage injection.
|
|
3
|
+
*/
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
module.exports = function (phantomas) {
|
|
7
|
+
const SESSION_STORAGE = "session-storage",
|
|
8
|
+
LOCAL_STORAGE = "local-storage";
|
|
9
|
+
|
|
10
|
+
phantomas.on("init", async (page) => {
|
|
11
|
+
let sessionStorage = phantomas.getParam(SESSION_STORAGE, false);
|
|
12
|
+
let localStorage = phantomas.getParam(LOCAL_STORAGE, false);
|
|
13
|
+
|
|
14
|
+
// Mapping given "storage-string" to json object if string has been given
|
|
15
|
+
if (typeof sessionStorage == "string" || sessionStorage instanceof String) {
|
|
16
|
+
sessionStorage = parseStorage(sessionStorage);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (typeof localStorage == "string" || localStorage instanceof String) {
|
|
20
|
+
localStorage = parseStorage(localStorage);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (sessionStorage) {
|
|
24
|
+
phantomas.log(
|
|
25
|
+
"Injecting sessionStorage: %j",
|
|
26
|
+
JSON.stringify(sessionStorage)
|
|
27
|
+
);
|
|
28
|
+
await injectStorage(page, sessionStorage, SESSION_STORAGE);
|
|
29
|
+
}
|
|
30
|
+
if (localStorage) {
|
|
31
|
+
phantomas.log("Injecting localStorag: %j", JSON.stringify(localStorage));
|
|
32
|
+
await injectStorage(page, localStorage, LOCAL_STORAGE);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
function parseStorage(storageString) {
|
|
37
|
+
// --sessionStorage='bar=foo;domain=url'
|
|
38
|
+
// --localStorage='bar=fooLocal;domain=urlLocal'
|
|
39
|
+
var storageMap = {};
|
|
40
|
+
storageString.split(";").forEach(function (singleEntry) {
|
|
41
|
+
var entryKeyValue = singleEntry.split("=");
|
|
42
|
+
storageMap[entryKeyValue[0]] = entryKeyValue[1];
|
|
43
|
+
});
|
|
44
|
+
return storageMap;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Inject the given storage into the specified page storage.
|
|
49
|
+
* Either localStorage or sessionStorage
|
|
50
|
+
*
|
|
51
|
+
* @param {Page} page in which page the storage should be injected
|
|
52
|
+
* @param {Object} storage the JSON object consisting of the storage keys and values
|
|
53
|
+
* @param {string} storageType either localStorage or sessionStorage
|
|
54
|
+
*/
|
|
55
|
+
async function injectStorage(page, storage, storageType) {
|
|
56
|
+
if (!page || !storage || !storageType) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* istanbul ignore next */
|
|
61
|
+
await page.evaluateOnNewDocument(
|
|
62
|
+
(storage, storageType, SESSION_STORAGE, LOCAL_STORAGE) => {
|
|
63
|
+
const keys = Object.keys(storage);
|
|
64
|
+
const values = Object.values(storage);
|
|
65
|
+
if (storageType === SESSION_STORAGE) {
|
|
66
|
+
for (let i = 0; i < keys.length; i++) {
|
|
67
|
+
sessionStorage.setItem(keys[i], values[i]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (storageType === LOCAL_STORAGE) {
|
|
71
|
+
for (let i = 0; i < keys.length; i++) {
|
|
72
|
+
localStorage.setItem(keys[i], values[i]);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
storage,
|
|
77
|
+
storageType,
|
|
78
|
+
SESSION_STORAGE,
|
|
79
|
+
LOCAL_STORAGE
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
@@ -21,7 +21,10 @@ module.exports = function (phantomas) {
|
|
|
21
21
|
return new Promise(async (resolve) => {
|
|
22
22
|
phantomas.log("Scrolling the page...");
|
|
23
23
|
|
|
24
|
+
/* istanbul ignore next */
|
|
24
25
|
await page.evaluate(() => document.body.scrollIntoView(false));
|
|
26
|
+
|
|
27
|
+
/* istanbul ignore next */
|
|
25
28
|
const scrollOffset = await page.evaluate(() => document.body.scrollTop);
|
|
26
29
|
|
|
27
30
|
// wait for lazy loading to do its job
|
package/hooks/build
CHANGED
package/lib/browser.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
/**
|
|
2
3
|
* Expose puppeteer API and events emitter object for lib/index.js
|
|
3
4
|
*/
|
|
@@ -11,7 +12,7 @@ function Browser() {
|
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Use the provided events emitter
|
|
14
|
-
* @param {EventEmitter} events
|
|
15
|
+
* @param {puppeteer.EventEmitter} events
|
|
15
16
|
*/
|
|
16
17
|
Browser.prototype.bind = (events) => (this.events = events);
|
|
17
18
|
|
|
@@ -36,6 +37,7 @@ Browser.prototype.init = async (phantomasOptions) => {
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
// customize path to Chromium binary
|
|
40
|
+
/* istanbul ignore next */
|
|
39
41
|
if (env["PHANTOMAS_CHROMIUM_EXECUTABLE"]) {
|
|
40
42
|
options.executablePath = env["PHANTOMAS_CHROMIUM_EXECUTABLE"];
|
|
41
43
|
}
|
|
@@ -43,6 +45,7 @@ Browser.prototype.init = async (phantomasOptions) => {
|
|
|
43
45
|
// detect that we run inside a container
|
|
44
46
|
// @see https://github.com/jessfraz/dockerfiles/issues/65
|
|
45
47
|
// @see https://github.com/Zenika/alpine-chrome#-the-best-with-seccomp
|
|
48
|
+
/* istanbul ignore next */
|
|
46
49
|
if (env["DOCKERIZED"]) {
|
|
47
50
|
debug("Docker environment detected");
|
|
48
51
|
debug(
|
|
@@ -53,6 +56,7 @@ Browser.prototype.init = async (phantomasOptions) => {
|
|
|
53
56
|
// detect that we run inside an Amazon Lambda machine
|
|
54
57
|
// (note: the LAMBDA_TASK_ROOT env variable is automatically set by AWS)
|
|
55
58
|
// @see https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime
|
|
59
|
+
/* istanbul ignore next */
|
|
56
60
|
if (env["LAMBDA_TASK_ROOT"]) {
|
|
57
61
|
// Chrome then requires some more flags
|
|
58
62
|
options.args.push(
|
|
@@ -69,13 +73,13 @@ Browser.prototype.init = async (phantomasOptions) => {
|
|
|
69
73
|
// https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#puppeteerlaunchoptions
|
|
70
74
|
this.browser = await puppeteer.launch(options);
|
|
71
75
|
this.page = await this.browser.newPage();
|
|
72
|
-
} catch (ex) {
|
|
76
|
+
} catch (ex) /* istanbul ignore next */ {
|
|
73
77
|
debug("Puppeteer failed to launch: %s", ex);
|
|
74
78
|
throw ex;
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
// A Chrome Devtools Protocol session attached to the target
|
|
78
|
-
this.cdp = this.page._client;
|
|
82
|
+
this.cdp = this.page._client();
|
|
79
83
|
|
|
80
84
|
debug("Using binary from: %s", this.browser.process().spawnfile);
|
|
81
85
|
|
|
@@ -94,13 +98,14 @@ Browser.prototype.init = async (phantomasOptions) => {
|
|
|
94
98
|
this.page.on("dialog", async (dialog) => {
|
|
95
99
|
// https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#class-dialog
|
|
96
100
|
const message = dialog.message();
|
|
97
|
-
|
|
101
|
+
const type = dialog.type();
|
|
102
|
+
debug("dialog: %s [%s]", type, message);
|
|
98
103
|
|
|
99
|
-
switch (
|
|
104
|
+
switch (type) {
|
|
100
105
|
case "alert":
|
|
101
106
|
case "confirm":
|
|
102
107
|
case "prompt":
|
|
103
|
-
this.events.emit(
|
|
108
|
+
this.events.emit(type, message); // @desc Emitted when a JavaScript dialog appears: alert, prompt or confirm
|
|
104
109
|
break;
|
|
105
110
|
}
|
|
106
111
|
|
|
@@ -167,6 +172,7 @@ Browser.prototype.init = async (phantomasOptions) => {
|
|
|
167
172
|
this.onRequestLoaded = (eventName, data) => {
|
|
168
173
|
var meta = responses[data.requestId];
|
|
169
174
|
|
|
175
|
+
/* istanbul ignore if */
|
|
170
176
|
if (typeof meta === "undefined") {
|
|
171
177
|
// the browser sometimes looses trace of a request, let's ignore.
|
|
172
178
|
networkDebug(
|
|
@@ -307,7 +313,7 @@ Browser.prototype.visit = (url, waitUntil, timeout) => {
|
|
|
307
313
|
debug("Metrics: %s", JSON.stringify(metrics));
|
|
308
314
|
|
|
309
315
|
this.events.emit("metrics", metrics); // @desc Emitted when Chromuim's page.metrics() has been called
|
|
310
|
-
} catch (ex) {
|
|
316
|
+
} catch (ex) /* istanbul ignore next */ {
|
|
311
317
|
debug("Get metrics failed: " + ex);
|
|
312
318
|
return reject(ex);
|
|
313
319
|
}
|
|
@@ -325,7 +331,7 @@ Browser.prototype.close = async () => {
|
|
|
325
331
|
|
|
326
332
|
// The page is closed, let's close the browser
|
|
327
333
|
if (this.browser && this.browser.isConnected()) await this.browser.close();
|
|
328
|
-
} catch (ex) {
|
|
334
|
+
} catch (ex) /* istanbul ignore next */ {
|
|
329
335
|
debug("An exception was raised in Browser.prototype.close(): " + ex);
|
|
330
336
|
debug(ex);
|
|
331
337
|
}
|
package/lib/index.js
CHANGED
|
@@ -29,7 +29,7 @@ function phantomas(url, opts) {
|
|
|
29
29
|
debug("phantomas: %s", VERSION);
|
|
30
30
|
debug(
|
|
31
31
|
"Puppeteer: preferred revision r%s",
|
|
32
|
-
puppeteer.
|
|
32
|
+
puppeteer.default._preferredRevision
|
|
33
33
|
);
|
|
34
34
|
debug("URL: <%s>", url);
|
|
35
35
|
|
|
@@ -39,7 +39,7 @@ function phantomas(url, opts) {
|
|
|
39
39
|
|
|
40
40
|
debug("Options: %s", JSON.stringify(options));
|
|
41
41
|
|
|
42
|
-
events.setMaxListeners(
|
|
42
|
+
events.setMaxListeners(250); // MaxListenersExceededWarning: Possible EventEmitter memory leak detected.
|
|
43
43
|
|
|
44
44
|
var results = new Results();
|
|
45
45
|
results.setUrl(url);
|
|
@@ -82,7 +82,9 @@ function phantomas(url, opts) {
|
|
|
82
82
|
evaluate: page.evaluate.bind(page),
|
|
83
83
|
|
|
84
84
|
// @see https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#pageselector-1
|
|
85
|
-
querySelectorAll: async (
|
|
85
|
+
querySelectorAll: async function querySelectorAll(
|
|
86
|
+
selector
|
|
87
|
+
) /* istanbul ignore next */ {
|
|
86
88
|
debug('querySelectorAll("%s")', selector);
|
|
87
89
|
return page.$$(selector);
|
|
88
90
|
},
|
|
@@ -106,6 +108,7 @@ function phantomas(url, opts) {
|
|
|
106
108
|
|
|
107
109
|
// pass phantomas options to page scope
|
|
108
110
|
// https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#pageevaluateonnewdocumentpagefunction-args
|
|
111
|
+
/* istanbul ignore next */
|
|
109
112
|
await page.evaluateOnNewDocument((options) => {
|
|
110
113
|
window.__phantomas_options = options;
|
|
111
114
|
}, options);
|
|
@@ -132,6 +135,7 @@ function phantomas(url, opts) {
|
|
|
132
135
|
scope[type].apply(scope, args);
|
|
133
136
|
break;
|
|
134
137
|
|
|
138
|
+
/* istanbul ignore next */
|
|
135
139
|
default:
|
|
136
140
|
debug("Unrecognized event type: " + type);
|
|
137
141
|
}
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"init": {
|
|
64
64
|
"file": "/lib/index.js",
|
|
65
65
|
"desc": "Browser's scope and modules are set up, the page is about to be loaded",
|
|
66
|
-
"arguments": "page, browser"
|
|
66
|
+
"arguments": "page, browser.getPuppeteerBrowser("
|
|
67
67
|
},
|
|
68
68
|
"beforeClose": {
|
|
69
69
|
"file": "/lib/index.js",
|
|
@@ -102,6 +102,11 @@
|
|
|
102
102
|
"desc": "Saves the source of page being loaded to a file\nPlease note that saving each file takes a few ms.\nConsider increasing default timeout.\nRun phantomas with --page-source option to use this module.",
|
|
103
103
|
"options": []
|
|
104
104
|
},
|
|
105
|
+
"pageStorage": {
|
|
106
|
+
"file": "/extensions/pageStorage/pageStorage.js",
|
|
107
|
+
"desc": "",
|
|
108
|
+
"options": []
|
|
109
|
+
},
|
|
105
110
|
"postLoadDelay": {
|
|
106
111
|
"file": "/extensions/postLoadDelay/postLoadDelay.js",
|
|
107
112
|
"desc": "Delays report generation for a given time",
|
|
@@ -117,6 +122,11 @@
|
|
|
117
122
|
"desc": "Allow page to be scrolled after it is loaded\nPass --scroll as an option in CLI mode",
|
|
118
123
|
"options": []
|
|
119
124
|
},
|
|
125
|
+
"userAgent": {
|
|
126
|
+
"file": "/extensions/userAgent/userAgent.js",
|
|
127
|
+
"desc": "Sets a user agent according to --user-agent or --phone or --tablet options",
|
|
128
|
+
"options": []
|
|
129
|
+
},
|
|
120
130
|
"viewport": {
|
|
121
131
|
"file": "/extensions/viewport/viewport.js",
|
|
122
132
|
"desc": "Provides the --viewport option to set any device resolution and pixel density ratio.\nIf the user sets a viewport size as well as a device option (--phone, --tablet, ...),\nwe assume that he or she wants to overwrite the device values.\nTwo syntaxes are supported:\n - 1200x800 will set a 1x pixel density ratio\n - 1200x800x2 will set the given ratio (float values such as 1.5 are accepted)",
|
|
@@ -1050,13 +1060,13 @@
|
|
|
1050
1060
|
"offenders": true,
|
|
1051
1061
|
"unit": "number",
|
|
1052
1062
|
"module": "assetsTypes",
|
|
1053
|
-
"testsCovered":
|
|
1063
|
+
"testsCovered": true
|
|
1054
1064
|
},
|
|
1055
1065
|
"videoSize": {
|
|
1056
1066
|
"desc": "size of video responses (with compression)",
|
|
1057
1067
|
"unit": "bytes",
|
|
1058
1068
|
"module": "assetsTypes",
|
|
1059
|
-
"testsCovered":
|
|
1069
|
+
"testsCovered": true
|
|
1060
1070
|
},
|
|
1061
1071
|
"base64Count": {
|
|
1062
1072
|
"desc": "number of base64 encoded \"responses\" (no HTTP request was actually made)",
|
|
@@ -1206,7 +1216,7 @@
|
|
|
1206
1216
|
"testsCovered": false
|
|
1207
1217
|
},
|
|
1208
1218
|
"recalcStyleDuration": {
|
|
1209
|
-
"desc": "combined duration of
|
|
1219
|
+
"desc": "combined duration of style recalculations",
|
|
1210
1220
|
"unit": "ms",
|
|
1211
1221
|
"module": "cpuTasks",
|
|
1212
1222
|
"testsCovered": false
|
|
@@ -1620,7 +1630,7 @@
|
|
|
1620
1630
|
"testsCovered": true
|
|
1621
1631
|
},
|
|
1622
1632
|
"oldTlsProtocol": {
|
|
1623
|
-
"desc": "number of domains using TLS 1.
|
|
1633
|
+
"desc": "number of domains using TLS 1.2",
|
|
1624
1634
|
"offenders": true,
|
|
1625
1635
|
"unit": "number",
|
|
1626
1636
|
"module": "protocols",
|
|
@@ -1868,6 +1878,6 @@
|
|
|
1868
1878
|
},
|
|
1869
1879
|
"metricsCount": 187,
|
|
1870
1880
|
"modulesCount": 36,
|
|
1871
|
-
"extensionsCount":
|
|
1872
|
-
"version": "2.
|
|
1881
|
+
"extensionsCount": 14,
|
|
1882
|
+
"version": "2.4.0"
|
|
1873
1883
|
}
|