lighthouse 9.4.0-dev.20220227 → 9.4.0-dev.20220228
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/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +1 -0
- package/lighthouse-cli/test/smokehouse/readme.md +14 -0
- package/lighthouse-cli/test/smokehouse/report-assert.js +61 -27
- package/lighthouse-cli/test/smokehouse/smokehouse.js +5 -2
- package/lighthouse-core/audits/dobetterweb/inspector-issues.js +6 -6
- package/lighthouse-core/gather/gatherers/inspector-issues.js +1 -1
- package/package.json +3 -3
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +1 -1
- package/types/artifacts.d.ts +1 -1
- package/types/smokehouse.d.ts +1 -1
|
@@ -186,6 +186,7 @@ async function begin() {
|
|
|
186
186
|
console.log('\n✨ Be sure to have recently run this: yarn build-all');
|
|
187
187
|
}
|
|
188
188
|
const {runLighthouse} = await import(runnerPath);
|
|
189
|
+
runLighthouse.runnerName = argv.runner;
|
|
189
190
|
|
|
190
191
|
// Find test definition file and filter by requestedTestIds.
|
|
191
192
|
let testDefnPath = argv.testsPath || coreTestDefnsPath;
|
|
@@ -66,6 +66,8 @@ However, if an array literal is used as the expectation, an extra condition is e
|
|
|
66
66
|
|
|
67
67
|
Arrays can be checked against a subset of elements using the special `_includes` property. The value of `_includes` _must_ be an array. Each assertion in `_includes` will remove the matching item from consideration for the rest.
|
|
68
68
|
|
|
69
|
+
Arrays can be asserted to not match any elements using the special `_excludes` property. The value of `_excludes` _must_ be an array. If an `_includes` check is defined before an `_excludes` check, only the element not matched under the previous will be considered.
|
|
70
|
+
|
|
69
71
|
**Examples**:
|
|
70
72
|
| Actual | Expected | Result |
|
|
71
73
|
| -- | -- | -- |
|
|
@@ -73,6 +75,9 @@ Arrays can be checked against a subset of elements using the special `_includes`
|
|
|
73
75
|
| `[{timeInMs: 5}, {timeInMs: 15}]` | `{length: 2}` | ✅ PASS |
|
|
74
76
|
| `[{timeInMs: 5}, {timeInMs: 15}]` | `{_includes: [{timeInMs: 5}]}` | ✅ PASS |
|
|
75
77
|
| `[{timeInMs: 5}, {timeInMs: 15}]` | `{_includes: [{timeInMs: 5}, {timeInMs: 5}]}` | ❌ FAIL |
|
|
78
|
+
| `[{timeInMs: 5}, {timeInMs: 15}]` | `{_includes: [{timeInMs: 5}], _excludes: [{timeInMs: 5}]}` | ✅ PASS |
|
|
79
|
+
| `[{timeInMs: 5}, {timeInMs: 15}]` | `{_includes: [{timeInMs: 5}], _excludes: [{timeInMs: 15}]}` | ❌ FAIL |
|
|
80
|
+
| `[{timeInMs: 5}, {timeInMs: 15}]` | `{_includes: [{timeInMs: 5}], _excludes: [{}]}` | ❌ FAIL |
|
|
76
81
|
| `[{timeInMs: 5}, {timeInMs: 15}]` | `[{timeInMs: 5}]` | ❌ FAIL |
|
|
77
82
|
|
|
78
83
|
### Special environment checks
|
|
@@ -104,6 +109,15 @@ If an expectation requires a minimum version of Chromium, use `_minChromiumMiles
|
|
|
104
109
|
},
|
|
105
110
|
```
|
|
106
111
|
|
|
112
|
+
All pruning checks:
|
|
113
|
+
|
|
114
|
+
- `_minChromiumMilestone`
|
|
115
|
+
- `_maxChromiumMilestone`
|
|
116
|
+
- `_legacyOnly`
|
|
117
|
+
- `_fraggleRockOnly`
|
|
118
|
+
- `_skipInBundled`
|
|
119
|
+
- `_runner` (set to same value provided to CLI --runner flag, ex: `'devtools'`)
|
|
120
|
+
|
|
107
121
|
## Pipeline
|
|
108
122
|
|
|
109
123
|
The different frontends launch smokehouse with a set of tests to run. Smokehouse then coordinates the tests using a particular method of running Lighthouse (CLI, as a bundle, etc).
|
|
@@ -103,6 +103,8 @@ function findDifference(path, actual, expected) {
|
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
let inclExclCopy;
|
|
107
|
+
|
|
106
108
|
// We only care that all expected's own properties are on actual (and not the other way around).
|
|
107
109
|
// Note an expected `undefined` can match an actual that is either `undefined` or not defined.
|
|
108
110
|
for (const key of Object.keys(expected)) {
|
|
@@ -112,6 +114,8 @@ function findDifference(path, actual, expected) {
|
|
|
112
114
|
const expectedValue = expected[key];
|
|
113
115
|
|
|
114
116
|
if (key === '_includes') {
|
|
117
|
+
inclExclCopy = [...actual];
|
|
118
|
+
|
|
115
119
|
if (!Array.isArray(expectedValue)) throw new Error('Array subset must be array');
|
|
116
120
|
if (!Array.isArray(actual)) {
|
|
117
121
|
return {
|
|
@@ -121,12 +125,12 @@ function findDifference(path, actual, expected) {
|
|
|
121
125
|
};
|
|
122
126
|
}
|
|
123
127
|
|
|
124
|
-
const actualCopy = [...actual];
|
|
125
128
|
for (const expectedEntry of expectedValue) {
|
|
126
129
|
const matchingIndex =
|
|
127
|
-
|
|
130
|
+
inclExclCopy.findIndex(actualEntry =>
|
|
131
|
+
!findDifference(keyPath, actualEntry, expectedEntry));
|
|
128
132
|
if (matchingIndex !== -1) {
|
|
129
|
-
|
|
133
|
+
inclExclCopy.splice(matchingIndex, 1);
|
|
130
134
|
continue;
|
|
131
135
|
}
|
|
132
136
|
|
|
@@ -140,6 +144,33 @@ function findDifference(path, actual, expected) {
|
|
|
140
144
|
continue;
|
|
141
145
|
}
|
|
142
146
|
|
|
147
|
+
if (key === '_excludes') {
|
|
148
|
+
// Re-use state from `_includes` check, if there was one.
|
|
149
|
+
/** @type {any[]} */
|
|
150
|
+
const arrToCheckAgainst = inclExclCopy || actual;
|
|
151
|
+
|
|
152
|
+
if (!Array.isArray(expectedValue)) throw new Error('Array subset must be array');
|
|
153
|
+
if (!Array.isArray(actual)) continue;
|
|
154
|
+
|
|
155
|
+
const expectedExclusions = expectedValue;
|
|
156
|
+
for (const expectedExclusion of expectedExclusions) {
|
|
157
|
+
const matchingIndex = arrToCheckAgainst.findIndex(actualEntry =>
|
|
158
|
+
!findDifference(keyPath, actualEntry, expectedExclusion));
|
|
159
|
+
if (matchingIndex !== -1) {
|
|
160
|
+
return {
|
|
161
|
+
path,
|
|
162
|
+
actual: arrToCheckAgainst[matchingIndex],
|
|
163
|
+
expected: {
|
|
164
|
+
message: 'Expected to not find matching entry via _excludes',
|
|
165
|
+
expectedExclusion,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
|
|
143
174
|
const actualValue = actual[key];
|
|
144
175
|
const subDifference = findDifference(keyPath, actualValue, expectedValue);
|
|
145
176
|
|
|
@@ -187,7 +218,7 @@ function makeComparison(name, actualResult, expectedResult) {
|
|
|
187
218
|
* @param {LocalConsole} localConsole
|
|
188
219
|
* @param {LH.Result} lhr
|
|
189
220
|
* @param {Smokehouse.ExpectedRunnerResult} expected
|
|
190
|
-
* @param {{isBundled?: boolean}=} reportOptions
|
|
221
|
+
* @param {{runner?: string, isBundled?: boolean}=} reportOptions
|
|
191
222
|
*/
|
|
192
223
|
function pruneExpectations(localConsole, lhr, expected, reportOptions) {
|
|
193
224
|
const isFraggleRock = lhr.configSettings.channel === 'fraggle-rock-cli';
|
|
@@ -217,8 +248,20 @@ function pruneExpectations(localConsole, lhr, expected, reportOptions) {
|
|
|
217
248
|
* @param {*} obj
|
|
218
249
|
*/
|
|
219
250
|
function pruneRecursively(obj) {
|
|
220
|
-
|
|
221
|
-
|
|
251
|
+
/**
|
|
252
|
+
* @param {string} key
|
|
253
|
+
*/
|
|
254
|
+
const remove = (key) => {
|
|
255
|
+
if (Array.isArray(obj)) {
|
|
256
|
+
obj.splice(Number(key), 1);
|
|
257
|
+
} else {
|
|
258
|
+
delete obj[key];
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// Because we may be deleting keys, we should iterate the keys backwards
|
|
263
|
+
// otherwise arrays with multiple pruning checks will skip elements.
|
|
264
|
+
for (const [key, value] of Object.entries(obj).reverse()) {
|
|
222
265
|
if (!value || typeof value !== 'object') {
|
|
223
266
|
continue;
|
|
224
267
|
}
|
|
@@ -229,42 +272,32 @@ function pruneExpectations(localConsole, lhr, expected, reportOptions) {
|
|
|
229
272
|
JSON.stringify(value, null, 2),
|
|
230
273
|
`Actual Chromium version: ${getChromeVersion()}`,
|
|
231
274
|
].join(' '));
|
|
232
|
-
|
|
233
|
-
obj.splice(Number(key), 1);
|
|
234
|
-
} else {
|
|
235
|
-
delete obj[key];
|
|
236
|
-
}
|
|
275
|
+
remove(key);
|
|
237
276
|
} else if (value._legacyOnly && isFraggleRock) {
|
|
238
277
|
localConsole.log([
|
|
239
278
|
`[${key}] marked legacy only but run is Fraggle Rock, pruning expectation:`,
|
|
240
279
|
JSON.stringify(value, null, 2),
|
|
241
280
|
].join(' '));
|
|
242
|
-
|
|
243
|
-
obj.splice(Number(key), 1);
|
|
244
|
-
} else {
|
|
245
|
-
delete obj[key];
|
|
246
|
-
}
|
|
281
|
+
remove(key);
|
|
247
282
|
} else if (value._fraggleRockOnly && !isFraggleRock) {
|
|
248
283
|
localConsole.log([
|
|
249
284
|
`[${key}] marked Fraggle Rock only but run is legacy, pruning expectation:`,
|
|
250
285
|
JSON.stringify(value, null, 2),
|
|
251
286
|
`Actual channel: ${lhr.configSettings.channel}`,
|
|
252
287
|
].join(' '));
|
|
253
|
-
|
|
254
|
-
obj.splice(Number(key), 1);
|
|
255
|
-
} else {
|
|
256
|
-
delete obj[key];
|
|
257
|
-
}
|
|
288
|
+
remove(key);
|
|
258
289
|
} else if (value._skipInBundled && !isBundled) {
|
|
259
290
|
localConsole.log([
|
|
260
291
|
`[${key}] marked as skip in bundled and runner is bundled, pruning expectation:`,
|
|
261
292
|
JSON.stringify(value, null, 2),
|
|
262
293
|
].join(' '));
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
294
|
+
remove(key);
|
|
295
|
+
} else if (value._runner && reportOptions?.runner !== value._runner) {
|
|
296
|
+
localConsole.log([
|
|
297
|
+
`[${key}] is only for runner ${value._runner}, pruning expectation:`,
|
|
298
|
+
JSON.stringify(value, null, 2),
|
|
299
|
+
].join(' '));
|
|
300
|
+
remove(key);
|
|
268
301
|
} else {
|
|
269
302
|
pruneRecursively(value);
|
|
270
303
|
}
|
|
@@ -275,6 +308,7 @@ function pruneExpectations(localConsole, lhr, expected, reportOptions) {
|
|
|
275
308
|
delete obj._skipInBundled;
|
|
276
309
|
delete obj._minChromiumMilestone;
|
|
277
310
|
delete obj._maxChromiumMilestone;
|
|
311
|
+
delete obj._runner;
|
|
278
312
|
}
|
|
279
313
|
|
|
280
314
|
const cloned = cloneDeep(expected);
|
|
@@ -420,7 +454,7 @@ function reportAssertion(localConsole, assertion) {
|
|
|
420
454
|
* summary. Returns count of passed and failed tests.
|
|
421
455
|
* @param {{lhr: LH.Result, artifacts: LH.Artifacts, networkRequests?: string[]}} actual
|
|
422
456
|
* @param {Smokehouse.ExpectedRunnerResult} expected
|
|
423
|
-
* @param {{isDebug?: boolean, isBundled?: boolean}=} reportOptions
|
|
457
|
+
* @param {{runner?: string, isDebug?: boolean, isBundled?: boolean}=} reportOptions
|
|
424
458
|
* @return {{passed: number, failed: number, log: string}}
|
|
425
459
|
*/
|
|
426
460
|
function getAssertionReport(actual, expected, reportOptions = {}) {
|
|
@@ -57,7 +57,7 @@ async function runSmokehouse(smokeTestDefns, smokehouseOptions) {
|
|
|
57
57
|
useFraggleRock,
|
|
58
58
|
jobs = DEFAULT_CONCURRENT_RUNS,
|
|
59
59
|
retries = DEFAULT_RETRIES,
|
|
60
|
-
lighthouseRunner = cliLighthouseRunner,
|
|
60
|
+
lighthouseRunner = Object.assign(cliLighthouseRunner, {runnerName: 'cli'}),
|
|
61
61
|
takeNetworkRequestUrls,
|
|
62
62
|
} = smokehouseOptions;
|
|
63
63
|
assertPositiveInteger('jobs', jobs);
|
|
@@ -159,7 +159,10 @@ async function runSmokeTest(smokeTestDefn, testOptions) {
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
// Assert result.
|
|
162
|
-
report = getAssertionReport(result, expectations, {
|
|
162
|
+
report = getAssertionReport(result, expectations, {
|
|
163
|
+
runner: lighthouseRunner.runnerName,
|
|
164
|
+
isDebug,
|
|
165
|
+
});
|
|
163
166
|
|
|
164
167
|
runs.push({
|
|
165
168
|
...result,
|
|
@@ -71,19 +71,19 @@ class IssuesPanelEntries extends Audit {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
* @param {Array<LH.Crdp.Audits.
|
|
74
|
+
* @param {Array<LH.Crdp.Audits.CookieIssueDetails>} CookieIssues
|
|
75
75
|
* @return {LH.Audit.Details.TableItem}
|
|
76
76
|
*/
|
|
77
|
-
static
|
|
77
|
+
static getCookieRow(CookieIssues) {
|
|
78
78
|
const requestUrls = new Set();
|
|
79
|
-
for (const issue of
|
|
79
|
+
for (const issue of CookieIssues) {
|
|
80
80
|
const requestUrl = (issue.request?.url) || issue.cookieUrl;
|
|
81
81
|
if (requestUrl) {
|
|
82
82
|
requestUrls.add(requestUrl);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
return {
|
|
86
|
-
issueType: '
|
|
86
|
+
issueType: 'Cookie',
|
|
87
87
|
subItems: {
|
|
88
88
|
type: 'subitems',
|
|
89
89
|
items: Array.from(requestUrls).map(url => {
|
|
@@ -164,8 +164,8 @@ class IssuesPanelEntries extends Audit {
|
|
|
164
164
|
if (issues.mixedContentIssue.length) {
|
|
165
165
|
items.push(this.getMixedContentRow(issues.mixedContentIssue));
|
|
166
166
|
}
|
|
167
|
-
if (issues.
|
|
168
|
-
items.push(this.
|
|
167
|
+
if (issues.cookieIssue.length) {
|
|
168
|
+
items.push(this.getCookieRow(issues.cookieIssue));
|
|
169
169
|
}
|
|
170
170
|
if (issues.blockedByResponseIssue.length) {
|
|
171
171
|
items.push(this.getBlockedByResponseRow(issues.blockedByResponseIssue));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lighthouse",
|
|
3
|
-
"version": "9.4.0-dev.
|
|
3
|
+
"version": "9.4.0-dev.20220228",
|
|
4
4
|
"description": "Automated auditing, performance metrics, and best practices for the web.",
|
|
5
5
|
"main": "./lighthouse-core/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
"cpy": "^8.1.2",
|
|
141
141
|
"cross-env": "^7.0.2",
|
|
142
142
|
"csv-validator": "^0.0.3",
|
|
143
|
-
"devtools-protocol": "0.0.
|
|
143
|
+
"devtools-protocol": "0.0.975298",
|
|
144
144
|
"es-main": "^1.0.2",
|
|
145
145
|
"eslint": "^8.4.1",
|
|
146
146
|
"eslint-config-google": "^0.14.0",
|
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
"yargs-parser": "^21.0.0"
|
|
214
214
|
},
|
|
215
215
|
"resolutions": {
|
|
216
|
-
"puppeteer/**/devtools-protocol": "0.0.
|
|
216
|
+
"puppeteer/**/devtools-protocol": "0.0.975298"
|
|
217
217
|
},
|
|
218
218
|
"repository": "GoogleChrome/lighthouse",
|
|
219
219
|
"keywords": [
|
|
@@ -38,6 +38,7 @@ Array [
|
|
|
38
38
|
"blockedByResponseIssueDetails",
|
|
39
39
|
"clientHintIssueDetails",
|
|
40
40
|
"contentSecurityPolicyIssueDetails",
|
|
41
|
+
"cookieIssueDetails",
|
|
41
42
|
"corsIssueDetails",
|
|
42
43
|
"deprecationIssueDetails",
|
|
43
44
|
"federatedAuthRequestIssueDetails",
|
|
@@ -47,7 +48,6 @@ Array [
|
|
|
47
48
|
"mixedContentIssueDetails",
|
|
48
49
|
"navigatorUserAgentIssueDetails",
|
|
49
50
|
"quirksModeIssueDetails",
|
|
50
|
-
"sameSiteCookieIssueDetails",
|
|
51
51
|
"sharedArrayBufferIssueDetails",
|
|
52
52
|
"twaQualityEnforcementDetails",
|
|
53
53
|
]
|
package/types/artifacts.d.ts
CHANGED
|
@@ -566,7 +566,7 @@ declare module Artifacts {
|
|
|
566
566
|
mixedContentIssue: LH.Crdp.Audits.MixedContentIssueDetails[];
|
|
567
567
|
navigatorUserAgentIssue: LH.Crdp.Audits.NavigatorUserAgentIssueDetails[];
|
|
568
568
|
quirksModeIssue: LH.Crdp.Audits.QuirksModeIssueDetails[];
|
|
569
|
-
|
|
569
|
+
cookieIssue: LH.Crdp.Audits.CookieIssueDetails[];
|
|
570
570
|
sharedArrayBufferIssue: LH.Crdp.Audits.SharedArrayBufferIssueDetails[];
|
|
571
571
|
twaQualityEnforcement: LH.Crdp.Audits.TrustedWebActivityIssueDetails[];
|
|
572
572
|
}
|
package/types/smokehouse.d.ts
CHANGED
|
@@ -52,7 +52,7 @@ declare global {
|
|
|
52
52
|
{expectations: Smokehouse.ExpectedRunnerResult | Array<Smokehouse.ExpectedRunnerResult>}
|
|
53
53
|
|
|
54
54
|
export type LighthouseRunner =
|
|
55
|
-
(url: string, configJson?: Config.Json, runnerOptions?: {isDebug?: boolean; useFraggleRock?: boolean}) => Promise<{lhr: LHResult, artifacts: Artifacts, log: string}
|
|
55
|
+
{runnerName?: string} & ((url: string, configJson?: Config.Json, runnerOptions?: {isDebug?: boolean; useFraggleRock?: boolean}) => Promise<{lhr: LHResult, artifacts: Artifacts, log: string}>);
|
|
56
56
|
|
|
57
57
|
export interface SmokehouseOptions {
|
|
58
58
|
/** If true, performs extra logging from the test runs. */
|