lighthouse 11.2.0-dev.20231017 → 11.2.0-dev.20231018
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/cli/test/smokehouse/frontends/smokehouse-bin.js +18 -7
- package/cli/test/smokehouse/lighthouse-runners/bundle.d.ts +2 -4
- package/cli/test/smokehouse/lighthouse-runners/bundle.js +8 -4
- package/cli/test/smokehouse/lighthouse-runners/cli.d.ts +2 -4
- package/cli/test/smokehouse/lighthouse-runners/cli.js +5 -3
- package/cli/test/smokehouse/lighthouse-runners/devtools.d.ts +2 -1
- package/cli/test/smokehouse/lighthouse-runners/devtools.js +3 -1
- package/cli/test/smokehouse/smokehouse.d.ts +4 -2
- package/cli/test/smokehouse/smokehouse.js +10 -7
- package/core/config/config.d.ts +1 -2
- package/core/config/config.js +18 -62
- package/core/config/constants.d.ts +1 -3
- package/core/config/constants.js +2 -18
- package/core/config/filters.d.ts +0 -8
- package/core/config/filters.js +0 -28
- package/core/config/validation.d.ts +4 -15
- package/core/config/validation.js +18 -63
- package/core/gather/base-artifacts.d.ts +2 -2
- package/core/gather/base-artifacts.js +5 -5
- package/core/gather/driver/navigation.d.ts +1 -1
- package/core/gather/driver/navigation.js +1 -1
- package/core/gather/driver/prepare.d.ts +3 -18
- package/core/gather/driver/prepare.js +14 -38
- package/core/gather/navigation-runner.d.ts +3 -31
- package/core/gather/navigation-runner.js +39 -112
- package/core/lib/navigation-error.d.ts +1 -2
- package/core/lib/navigation-error.js +2 -6
- package/package.json +1 -1
- package/types/config.d.ts +0 -38
- package/types/internal/smokehouse.d.ts +10 -5
|
@@ -21,7 +21,7 @@ import yargs from 'yargs';
|
|
|
21
21
|
import * as yargsHelpers from 'yargs/helpers';
|
|
22
22
|
import log from 'lighthouse-logger';
|
|
23
23
|
|
|
24
|
-
import {runSmokehouse, getShardedDefinitions} from '../smokehouse.js';
|
|
24
|
+
import {runSmokehouse, getShardedDefinitions, DEFAULT_RETRIES, DEFAULT_CONCURRENT_RUNS} from '../smokehouse.js';
|
|
25
25
|
import {updateTestDefnFormat} from './back-compat-util.js';
|
|
26
26
|
import {LH_ROOT} from '../../../../shared/root.js';
|
|
27
27
|
import exclusions from '../config/exclusions.js';
|
|
@@ -139,10 +139,12 @@ async function begin() {
|
|
|
139
139
|
'jobs': {
|
|
140
140
|
type: 'number',
|
|
141
141
|
alias: 'j',
|
|
142
|
+
default: DEFAULT_CONCURRENT_RUNS,
|
|
142
143
|
describe: 'Manually set the number of jobs to run at once. `1` runs all tests serially',
|
|
143
144
|
},
|
|
144
145
|
'retries': {
|
|
145
146
|
type: 'number',
|
|
147
|
+
default: DEFAULT_RETRIES,
|
|
146
148
|
describe: 'The number of times to retry failing tests before accepting. Defaults to 0',
|
|
147
149
|
},
|
|
148
150
|
'runner': {
|
|
@@ -164,6 +166,15 @@ async function begin() {
|
|
|
164
166
|
default: false,
|
|
165
167
|
describe: 'Ignore any smoke test exclusions set.',
|
|
166
168
|
},
|
|
169
|
+
'headless': {
|
|
170
|
+
type: 'boolean',
|
|
171
|
+
default: true,
|
|
172
|
+
hidden: true,
|
|
173
|
+
},
|
|
174
|
+
'no-headless': {
|
|
175
|
+
type: 'boolean',
|
|
176
|
+
describe: 'Launch Chrome in typical desktop headful mode, rather than our default of `--headless=new` (https://developer.chrome.com/articles/new-headless/).', // eslint-disable-line max-len
|
|
177
|
+
},
|
|
167
178
|
})
|
|
168
179
|
.wrap(y.terminalWidth())
|
|
169
180
|
.argv;
|
|
@@ -173,9 +184,6 @@ async function begin() {
|
|
|
173
184
|
const argv =
|
|
174
185
|
/** @type {Awaited<typeof rawArgv> & LH.Util.CamelCasify<Awaited<typeof rawArgv>>} */ (rawArgv);
|
|
175
186
|
|
|
176
|
-
const jobs = Number.isFinite(argv.jobs) ? argv.jobs : undefined;
|
|
177
|
-
const retries = Number.isFinite(argv.retries) ? argv.retries : undefined;
|
|
178
|
-
|
|
179
187
|
const runnerPath = runnerPaths[/** @type {keyof typeof runnerPaths} */ (argv.runner)];
|
|
180
188
|
if (argv.runner === 'bundle') {
|
|
181
189
|
console.log('\n✨ Be sure to have recently run this: yarn build-all');
|
|
@@ -210,9 +218,12 @@ async function begin() {
|
|
|
210
218
|
|
|
211
219
|
const prunedTestDefns = pruneExpectedNetworkRequests(testDefns, takeNetworkRequestUrls);
|
|
212
220
|
const options = {
|
|
213
|
-
jobs,
|
|
214
|
-
retries,
|
|
215
|
-
|
|
221
|
+
jobs: argv.jobs,
|
|
222
|
+
retries: argv.retries,
|
|
223
|
+
testRunnerOptions: {
|
|
224
|
+
isDebug: argv.debug,
|
|
225
|
+
headless: argv.headless,
|
|
226
|
+
},
|
|
216
227
|
lighthouseRunner: runLighthouse,
|
|
217
228
|
takeNetworkRequestUrls,
|
|
218
229
|
setup,
|
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
* Launch Chrome and do a full Lighthouse run via the Lighthouse DevTools bundle.
|
|
3
3
|
* @param {string} url
|
|
4
4
|
* @param {LH.Config=} config
|
|
5
|
-
* @param {
|
|
5
|
+
* @param {Smokehouse.SmokehouseOptions['testRunnerOptions']=} testRunnerOptions
|
|
6
6
|
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
|
|
7
7
|
*/
|
|
8
|
-
export function runLighthouse(url: string, config?: LH.Config | undefined, testRunnerOptions?: {
|
|
9
|
-
isDebug?: boolean;
|
|
10
|
-
} | undefined): Promise<{
|
|
8
|
+
export function runLighthouse(url: string, config?: LH.Config | undefined, testRunnerOptions?: Smokehouse.SmokehouseOptions['testRunnerOptions'] | undefined): Promise<{
|
|
11
9
|
lhr: LH.Result;
|
|
12
10
|
artifacts: LH.Artifacts;
|
|
13
11
|
log: string;
|
|
@@ -46,7 +46,7 @@ if (!isMainThread && parentPort) {
|
|
|
46
46
|
/**
|
|
47
47
|
* @param {string} url
|
|
48
48
|
* @param {LH.Config|undefined} config
|
|
49
|
-
* @param {
|
|
49
|
+
* @param {Smokehouse.SmokehouseOptions['testRunnerOptions']} testRunnerOptions
|
|
50
50
|
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts}>}
|
|
51
51
|
*/
|
|
52
52
|
async function runBundledLighthouse(url, config, testRunnerOptions) {
|
|
@@ -74,12 +74,16 @@ async function runBundledLighthouse(url, config, testRunnerOptions) {
|
|
|
74
74
|
const lighthouse = global.runBundledLighthouse;
|
|
75
75
|
|
|
76
76
|
// Launch and connect to Chrome.
|
|
77
|
-
const launchedChrome = await ChromeLauncher.launch(
|
|
77
|
+
const launchedChrome = await ChromeLauncher.launch({
|
|
78
|
+
chromeFlags: [
|
|
79
|
+
testRunnerOptions?.headless ? '--headless=new' : '',
|
|
80
|
+
],
|
|
81
|
+
});
|
|
78
82
|
const port = launchedChrome.port;
|
|
79
83
|
|
|
80
84
|
// Run Lighthouse.
|
|
81
85
|
try {
|
|
82
|
-
const logLevel = testRunnerOptions
|
|
86
|
+
const logLevel = testRunnerOptions?.isDebug ? 'verbose' : 'info';
|
|
83
87
|
|
|
84
88
|
// Puppeteer is not included in the bundle, we must create the page here.
|
|
85
89
|
const browser = await puppeteer.connect({browserURL: `http://127.0.0.1:${port}`});
|
|
@@ -101,7 +105,7 @@ async function runBundledLighthouse(url, config, testRunnerOptions) {
|
|
|
101
105
|
* Launch Chrome and do a full Lighthouse run via the Lighthouse DevTools bundle.
|
|
102
106
|
* @param {string} url
|
|
103
107
|
* @param {LH.Config=} config
|
|
104
|
-
* @param {
|
|
108
|
+
* @param {Smokehouse.SmokehouseOptions['testRunnerOptions']=} testRunnerOptions
|
|
105
109
|
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
|
|
106
110
|
*/
|
|
107
111
|
async function runLighthouse(url, config, testRunnerOptions = {}) {
|
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
* Launch Chrome and do a full Lighthouse run via the Lighthouse CLI.
|
|
3
3
|
* @param {string} url
|
|
4
4
|
* @param {LH.Config=} config
|
|
5
|
-
* @param {
|
|
5
|
+
* @param {Smokehouse.SmokehouseOptions['testRunnerOptions']=} testRunnerOptions
|
|
6
6
|
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
|
|
7
7
|
*/
|
|
8
|
-
export function runLighthouse(url: string, config?: LH.Config | undefined, testRunnerOptions?: {
|
|
9
|
-
isDebug?: boolean | undefined;
|
|
10
|
-
} | undefined): Promise<{
|
|
8
|
+
export function runLighthouse(url: string, config?: LH.Config | undefined, testRunnerOptions?: Smokehouse.SmokehouseOptions['testRunnerOptions'] | undefined): Promise<{
|
|
11
9
|
lhr: LH.Result;
|
|
12
10
|
artifacts: LH.Artifacts;
|
|
13
11
|
log: string;
|
|
@@ -28,7 +28,7 @@ const execFileAsync = promisify(execFile);
|
|
|
28
28
|
* Launch Chrome and do a full Lighthouse run via the Lighthouse CLI.
|
|
29
29
|
* @param {string} url
|
|
30
30
|
* @param {LH.Config=} config
|
|
31
|
-
* @param {
|
|
31
|
+
* @param {Smokehouse.SmokehouseOptions['testRunnerOptions']=} testRunnerOptions
|
|
32
32
|
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
|
|
33
33
|
*/
|
|
34
34
|
async function runLighthouse(url, config, testRunnerOptions = {}) {
|
|
@@ -46,11 +46,11 @@ async function runLighthouse(url, config, testRunnerOptions = {}) {
|
|
|
46
46
|
* @param {string} url
|
|
47
47
|
* @param {string} tmpPath
|
|
48
48
|
* @param {LH.Config=} config
|
|
49
|
-
* @param {
|
|
49
|
+
* @param {Smokehouse.SmokehouseOptions['testRunnerOptions']=} options
|
|
50
50
|
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
|
|
51
51
|
*/
|
|
52
52
|
async function internalRun(url, tmpPath, config, options) {
|
|
53
|
-
const {isDebug
|
|
53
|
+
const {isDebug, headless} = options || {};
|
|
54
54
|
const localConsole = new LocalConsole();
|
|
55
55
|
|
|
56
56
|
const outputPath = `${tmpPath}/smokehouse.report.json`;
|
|
@@ -67,6 +67,8 @@ async function internalRun(url, tmpPath, config, options) {
|
|
|
67
67
|
'--quiet',
|
|
68
68
|
];
|
|
69
69
|
|
|
70
|
+
if (headless) args.push('--chrome-flags="--headless=new"');
|
|
71
|
+
|
|
70
72
|
// Config can be optionally provided.
|
|
71
73
|
if (config) {
|
|
72
74
|
const configPath = `${tmpPath}/config.json`;
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* CHROME_PATH determines which Chrome is used–otherwise the default is puppeteer's chrome binary.
|
|
6
6
|
* @param {string} url
|
|
7
7
|
* @param {LH.Config=} config
|
|
8
|
+
* @param {Smokehouse.SmokehouseOptions['testRunnerOptions']=} testRunnerOptions
|
|
8
9
|
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
|
|
9
10
|
*/
|
|
10
|
-
export function runLighthouse(url: string, config?: LH.Config | undefined): Promise<{
|
|
11
|
+
export function runLighthouse(url: string, config?: LH.Config | undefined, testRunnerOptions?: Smokehouse.SmokehouseOptions['testRunnerOptions'] | undefined): Promise<{
|
|
11
12
|
lhr: LH.Result;
|
|
12
13
|
artifacts: LH.Artifacts;
|
|
13
14
|
log: string;
|
|
@@ -40,10 +40,12 @@ async function setup() {
|
|
|
40
40
|
* CHROME_PATH determines which Chrome is used–otherwise the default is puppeteer's chrome binary.
|
|
41
41
|
* @param {string} url
|
|
42
42
|
* @param {LH.Config=} config
|
|
43
|
+
* @param {Smokehouse.SmokehouseOptions['testRunnerOptions']=} testRunnerOptions
|
|
43
44
|
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
|
|
44
45
|
*/
|
|
45
|
-
async function runLighthouse(url, config) {
|
|
46
|
+
async function runLighthouse(url, config, testRunnerOptions) {
|
|
46
47
|
const chromeFlags = [
|
|
48
|
+
testRunnerOptions?.headless ? '--headless=new' : '',
|
|
47
49
|
`--custom-devtools-frontend=file://${devtoolsDir}/out/LighthouseIntegration/gen/front_end`,
|
|
48
50
|
];
|
|
49
51
|
const {lhr, artifacts, logs} = await testUrlFromDevtools(url, {
|
|
@@ -14,10 +14,10 @@ export type SmokehouseResult = {
|
|
|
14
14
|
/**
|
|
15
15
|
* Runs the selected smoke tests. Returns whether all assertions pass.
|
|
16
16
|
* @param {Array<Smokehouse.TestDfn>} smokeTestDefns
|
|
17
|
-
* @param {Smokehouse.SmokehouseOptions} smokehouseOptions
|
|
17
|
+
* @param {Partial<Smokehouse.SmokehouseOptions>} smokehouseOptions
|
|
18
18
|
* @return {Promise<{success: boolean, testResults: SmokehouseResult[]}>}
|
|
19
19
|
*/
|
|
20
|
-
export function runSmokehouse(smokeTestDefns: Array<Smokehouse.TestDfn>, smokehouseOptions: Smokehouse.SmokehouseOptions): Promise<{
|
|
20
|
+
export function runSmokehouse(smokeTestDefns: Array<Smokehouse.TestDfn>, smokehouseOptions: Partial<Smokehouse.SmokehouseOptions>): Promise<{
|
|
21
21
|
success: boolean;
|
|
22
22
|
testResults: SmokehouseResult[];
|
|
23
23
|
}>;
|
|
@@ -31,4 +31,6 @@ export function runSmokehouse(smokeTestDefns: Array<Smokehouse.TestDfn>, smokeho
|
|
|
31
31
|
* @return {Array<Smokehouse.TestDfn>}
|
|
32
32
|
*/
|
|
33
33
|
export function getShardedDefinitions(testDefns: Array<Smokehouse.TestDfn>, shardArg?: string | undefined): Array<Smokehouse.TestDfn>;
|
|
34
|
+
export const DEFAULT_RETRIES: 0;
|
|
35
|
+
export const DEFAULT_CONCURRENT_RUNS: 5;
|
|
34
36
|
//# sourceMappingURL=smokehouse.d.ts.map
|
|
@@ -46,12 +46,12 @@ const DEFAULT_RETRIES = 0;
|
|
|
46
46
|
/**
|
|
47
47
|
* Runs the selected smoke tests. Returns whether all assertions pass.
|
|
48
48
|
* @param {Array<Smokehouse.TestDfn>} smokeTestDefns
|
|
49
|
-
* @param {Smokehouse.SmokehouseOptions} smokehouseOptions
|
|
49
|
+
* @param {Partial<Smokehouse.SmokehouseOptions>} smokehouseOptions
|
|
50
50
|
* @return {Promise<{success: boolean, testResults: SmokehouseResult[]}>}
|
|
51
51
|
*/
|
|
52
52
|
async function runSmokehouse(smokeTestDefns, smokehouseOptions) {
|
|
53
53
|
const {
|
|
54
|
-
|
|
54
|
+
testRunnerOptions,
|
|
55
55
|
jobs = DEFAULT_CONCURRENT_RUNS,
|
|
56
56
|
retries = DEFAULT_RETRIES,
|
|
57
57
|
lighthouseRunner = Object.assign(cliLighthouseRunner, {runnerName: 'cli'}),
|
|
@@ -73,7 +73,8 @@ async function runSmokehouse(smokeTestDefns, smokehouseOptions) {
|
|
|
73
73
|
const concurrentMapper = new ConcurrentMapper();
|
|
74
74
|
|
|
75
75
|
const testOptions = {
|
|
76
|
-
|
|
76
|
+
testRunnerOptions,
|
|
77
|
+
jobs,
|
|
77
78
|
retries,
|
|
78
79
|
lighthouseRunner,
|
|
79
80
|
takeNetworkRequestUrls,
|
|
@@ -133,7 +134,7 @@ function purpleify(str) {
|
|
|
133
134
|
/**
|
|
134
135
|
* Run Lighthouse in the selected runner.
|
|
135
136
|
* @param {Smokehouse.TestDfn} smokeTestDefn
|
|
136
|
-
* @param {
|
|
137
|
+
* @param {Smokehouse.SmokehouseOptions} testOptions
|
|
137
138
|
* @return {Promise<SmokehouseResult>}
|
|
138
139
|
*/
|
|
139
140
|
async function runSmokeTest(smokeTestDefn, testOptions) {
|
|
@@ -141,7 +142,7 @@ async function runSmokeTest(smokeTestDefn, testOptions) {
|
|
|
141
142
|
const {
|
|
142
143
|
lighthouseRunner,
|
|
143
144
|
retries,
|
|
144
|
-
|
|
145
|
+
testRunnerOptions,
|
|
145
146
|
takeNetworkRequestUrls,
|
|
146
147
|
} = testOptions;
|
|
147
148
|
const requestedUrl = expectations.lhr.requestedUrl;
|
|
@@ -163,7 +164,7 @@ async function runSmokeTest(smokeTestDefn, testOptions) {
|
|
|
163
164
|
// Run Lighthouse.
|
|
164
165
|
try {
|
|
165
166
|
result = {
|
|
166
|
-
...await lighthouseRunner(requestedUrl, config,
|
|
167
|
+
...await lighthouseRunner(requestedUrl, config, testRunnerOptions),
|
|
167
168
|
networkRequests: takeNetworkRequestUrls ? takeNetworkRequestUrls() : undefined,
|
|
168
169
|
};
|
|
169
170
|
|
|
@@ -183,7 +184,7 @@ async function runSmokeTest(smokeTestDefn, testOptions) {
|
|
|
183
184
|
// Assert result.
|
|
184
185
|
report = getAssertionReport(result, expectations, {
|
|
185
186
|
runner: lighthouseRunner.runnerName,
|
|
186
|
-
|
|
187
|
+
...testRunnerOptions,
|
|
187
188
|
});
|
|
188
189
|
|
|
189
190
|
runs.push({
|
|
@@ -310,4 +311,6 @@ function getShardedDefinitions(testDefns, shardArg) {
|
|
|
310
311
|
export {
|
|
311
312
|
runSmokehouse,
|
|
312
313
|
getShardedDefinitions,
|
|
314
|
+
DEFAULT_RETRIES,
|
|
315
|
+
DEFAULT_CONCURRENT_RUNS,
|
|
313
316
|
};
|
package/core/config/config.d.ts
CHANGED
|
@@ -14,11 +14,10 @@ export function resolveWorkingCopy(config: LH.Config | undefined, context: {
|
|
|
14
14
|
* @param {LH.Gatherer.GatherMode} gatherMode
|
|
15
15
|
* @param {LH.Config=} config
|
|
16
16
|
* @param {LH.Flags=} flags
|
|
17
|
-
* @return {Promise<{resolvedConfig: LH.Config.ResolvedConfig
|
|
17
|
+
* @return {Promise<{resolvedConfig: LH.Config.ResolvedConfig}>}
|
|
18
18
|
*/
|
|
19
19
|
export function initializeConfig(gatherMode: LH.Gatherer.GatherMode, config?: LH.Config | undefined, flags?: LH.Flags | undefined): Promise<{
|
|
20
20
|
resolvedConfig: LH.Config.ResolvedConfig;
|
|
21
|
-
warnings: string[];
|
|
22
21
|
}>;
|
|
23
22
|
/**
|
|
24
23
|
* @param {LH.Config.ResolvedConfig} resolvedConfig
|
package/core/config/config.js
CHANGED
|
@@ -10,12 +10,11 @@ import log from 'lighthouse-logger';
|
|
|
10
10
|
|
|
11
11
|
import {Runner} from '../runner.js';
|
|
12
12
|
import defaultConfig from './default-config.js';
|
|
13
|
-
import {
|
|
13
|
+
import {nonSimulatedSettingsOverrides} from './constants.js'; // eslint-disable-line max-len
|
|
14
14
|
import {
|
|
15
15
|
throwInvalidDependencyOrder,
|
|
16
16
|
isValidArtifactDependency,
|
|
17
17
|
throwInvalidArtifactDependency,
|
|
18
|
-
assertArtifactTopologicalOrder,
|
|
19
18
|
assertValidConfig,
|
|
20
19
|
} from './validation.js';
|
|
21
20
|
import {filterConfigByGatherMode, filterConfigByExplicitFilters} from './filters.js';
|
|
@@ -192,66 +191,34 @@ function overrideSettingsForGatherMode(settings, gatherMode) {
|
|
|
192
191
|
/**
|
|
193
192
|
* Overrides the quiet windows when throttlingMethod requires observation.
|
|
194
193
|
*
|
|
195
|
-
* @param {LH.Config.NavigationDefn} navigation
|
|
196
194
|
* @param {LH.Config.Settings} settings
|
|
197
195
|
*/
|
|
198
|
-
function
|
|
199
|
-
if (navigation.disableThrottling) return;
|
|
196
|
+
function overrideThrottlingWindows(settings) {
|
|
200
197
|
if (settings.throttlingMethod === 'simulate') return;
|
|
201
198
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
199
|
+
settings.cpuQuietThresholdMs = Math.max(
|
|
200
|
+
settings.cpuQuietThresholdMs || 0,
|
|
201
|
+
nonSimulatedSettingsOverrides.cpuQuietThresholdMs
|
|
205
202
|
);
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
203
|
+
settings.networkQuietThresholdMs = Math.max(
|
|
204
|
+
settings.networkQuietThresholdMs || 0,
|
|
205
|
+
nonSimulatedSettingsOverrides.networkQuietThresholdMs
|
|
209
206
|
);
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
207
|
+
settings.pauseAfterFcpMs = Math.max(
|
|
208
|
+
settings.pauseAfterFcpMs || 0,
|
|
209
|
+
nonSimulatedSettingsOverrides.pauseAfterFcpMs
|
|
213
210
|
);
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
211
|
+
settings.pauseAfterLoadMs = Math.max(
|
|
212
|
+
settings.pauseAfterLoadMs || 0,
|
|
213
|
+
nonSimulatedSettingsOverrides.pauseAfterLoadMs
|
|
217
214
|
);
|
|
218
215
|
}
|
|
219
216
|
|
|
220
|
-
/**
|
|
221
|
-
* @param {LH.Config.AnyArtifactDefn[]|null|undefined} artifactDefns
|
|
222
|
-
* @param {LH.Config.Settings} settings
|
|
223
|
-
* @return {LH.Config.NavigationDefn[] | null}
|
|
224
|
-
*/
|
|
225
|
-
function resolveFakeNavigations(artifactDefns, settings) {
|
|
226
|
-
if (!artifactDefns) return null;
|
|
227
|
-
|
|
228
|
-
const status = {msg: 'Resolve navigation definitions', id: 'lh:config:resolveNavigationsToDefns'};
|
|
229
|
-
log.time(status, 'verbose');
|
|
230
|
-
|
|
231
|
-
const resolvedNavigation = {
|
|
232
|
-
...defaultNavigationConfig,
|
|
233
|
-
artifacts: artifactDefns,
|
|
234
|
-
pauseAfterFcpMs: settings.pauseAfterFcpMs,
|
|
235
|
-
pauseAfterLoadMs: settings.pauseAfterLoadMs,
|
|
236
|
-
networkQuietThresholdMs: settings.networkQuietThresholdMs,
|
|
237
|
-
cpuQuietThresholdMs: settings.cpuQuietThresholdMs,
|
|
238
|
-
blankPage: settings.blankPage,
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
overrideNavigationThrottlingWindows(resolvedNavigation, settings);
|
|
242
|
-
|
|
243
|
-
const navigations = [resolvedNavigation];
|
|
244
|
-
assertArtifactTopologicalOrder(navigations);
|
|
245
|
-
|
|
246
|
-
log.timeEnd(status);
|
|
247
|
-
return navigations;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
217
|
/**
|
|
251
218
|
* @param {LH.Gatherer.GatherMode} gatherMode
|
|
252
219
|
* @param {LH.Config=} config
|
|
253
220
|
* @param {LH.Flags=} flags
|
|
254
|
-
* @return {Promise<{resolvedConfig: LH.Config.ResolvedConfig
|
|
221
|
+
* @return {Promise<{resolvedConfig: LH.Config.ResolvedConfig}>}
|
|
255
222
|
*/
|
|
256
223
|
async function initializeConfig(gatherMode, config, flags = {}) {
|
|
257
224
|
const status = {msg: 'Initialize config', id: 'lh:config'};
|
|
@@ -264,28 +231,26 @@ async function initializeConfig(gatherMode, config, flags = {}) {
|
|
|
264
231
|
|
|
265
232
|
const settings = resolveSettings(configWorkingCopy.settings || {}, flags);
|
|
266
233
|
overrideSettingsForGatherMode(settings, gatherMode);
|
|
234
|
+
overrideThrottlingWindows(settings);
|
|
267
235
|
|
|
268
236
|
const artifacts = await resolveArtifactsToDefns(configWorkingCopy.artifacts, configDir);
|
|
269
237
|
|
|
270
|
-
const navigations = resolveFakeNavigations(artifacts, settings);
|
|
271
|
-
|
|
272
238
|
/** @type {LH.Config.ResolvedConfig} */
|
|
273
239
|
let resolvedConfig = {
|
|
274
240
|
artifacts,
|
|
275
|
-
navigations,
|
|
276
241
|
audits: await resolveAuditsToDefns(configWorkingCopy.audits, configDir),
|
|
277
242
|
categories: configWorkingCopy.categories || null,
|
|
278
243
|
groups: configWorkingCopy.groups || null,
|
|
279
244
|
settings,
|
|
280
245
|
};
|
|
281
246
|
|
|
282
|
-
|
|
247
|
+
assertValidConfig(resolvedConfig);
|
|
283
248
|
|
|
284
249
|
resolvedConfig = filterConfigByGatherMode(resolvedConfig, gatherMode);
|
|
285
250
|
resolvedConfig = filterConfigByExplicitFilters(resolvedConfig, settings);
|
|
286
251
|
|
|
287
252
|
log.timeEnd(status);
|
|
288
|
-
return {resolvedConfig
|
|
253
|
+
return {resolvedConfig};
|
|
289
254
|
}
|
|
290
255
|
|
|
291
256
|
/**
|
|
@@ -296,15 +261,6 @@ function getConfigDisplayString(resolvedConfig) {
|
|
|
296
261
|
/** @type {LH.Config.ResolvedConfig} */
|
|
297
262
|
const resolvedConfigCopy = JSON.parse(JSON.stringify(resolvedConfig));
|
|
298
263
|
|
|
299
|
-
if (resolvedConfigCopy.navigations) {
|
|
300
|
-
for (const navigation of resolvedConfigCopy.navigations) {
|
|
301
|
-
for (let i = 0; i < navigation.artifacts.length; ++i) {
|
|
302
|
-
// @ts-expect-error Breaking the Config.AnyArtifactDefn type.
|
|
303
|
-
navigation.artifacts[i] = navigation.artifacts[i].id;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
264
|
if (resolvedConfigCopy.artifacts) {
|
|
309
265
|
for (const artifactDefn of resolvedConfigCopy.artifacts) {
|
|
310
266
|
// @ts-expect-error Breaking the Config.AnyArtifactDefn type.
|
|
@@ -48,9 +48,7 @@ export namespace userAgents {
|
|
|
48
48
|
}
|
|
49
49
|
/** @type {LH.Config.Settings} */
|
|
50
50
|
export const defaultSettings: LH.Config.Settings;
|
|
51
|
-
|
|
52
|
-
export const defaultNavigationConfig: Required<LH.Config.NavigationJson>;
|
|
53
|
-
export namespace nonSimulatedPassConfigOverrides {
|
|
51
|
+
export namespace nonSimulatedSettingsOverrides {
|
|
54
52
|
const pauseAfterFcpMs: number;
|
|
55
53
|
const pauseAfterLoadMs: number;
|
|
56
54
|
const networkQuietThresholdMs: number;
|
package/core/config/constants.js
CHANGED
|
@@ -127,22 +127,7 @@ const defaultSettings = {
|
|
|
127
127
|
skipAudits: null,
|
|
128
128
|
};
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
const defaultNavigationConfig = {
|
|
132
|
-
id: 'defaultPass',
|
|
133
|
-
loadFailureMode: 'fatal',
|
|
134
|
-
disableThrottling: false,
|
|
135
|
-
disableStorageReset: false,
|
|
136
|
-
pauseAfterFcpMs: 0,
|
|
137
|
-
pauseAfterLoadMs: 0,
|
|
138
|
-
networkQuietThresholdMs: 0,
|
|
139
|
-
cpuQuietThresholdMs: 0,
|
|
140
|
-
blockedUrlPatterns: [],
|
|
141
|
-
blankPage: 'about:blank',
|
|
142
|
-
artifacts: [],
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const nonSimulatedPassConfigOverrides = {
|
|
130
|
+
const nonSimulatedSettingsOverrides = {
|
|
146
131
|
pauseAfterFcpMs: 5250,
|
|
147
132
|
pauseAfterLoadMs: 5250,
|
|
148
133
|
networkQuietThresholdMs: 5250,
|
|
@@ -154,6 +139,5 @@ export {
|
|
|
154
139
|
screenEmulationMetrics,
|
|
155
140
|
userAgents,
|
|
156
141
|
defaultSettings,
|
|
157
|
-
|
|
158
|
-
nonSimulatedPassConfigOverrides,
|
|
142
|
+
nonSimulatedSettingsOverrides,
|
|
159
143
|
};
|
package/core/config/filters.d.ts
CHANGED
|
@@ -31,14 +31,6 @@ export function filterArtifactsByGatherMode(artifacts: LH.Config.ResolvedConfig[
|
|
|
31
31
|
* @return {LH.Config.ResolvedConfig['artifacts']}
|
|
32
32
|
*/
|
|
33
33
|
export function filterArtifactsByAvailableAudits(artifacts: LH.Config.ResolvedConfig['artifacts'], audits: LH.Config.ResolvedConfig['audits']): LH.Config.ResolvedConfig['artifacts'];
|
|
34
|
-
/**
|
|
35
|
-
* Filters an array of navigations down to the set supported by the available artifacts.
|
|
36
|
-
*
|
|
37
|
-
* @param {LH.Config.ResolvedConfig['navigations']} navigations
|
|
38
|
-
* @param {Array<LH.Config.AnyArtifactDefn>} availableArtifacts
|
|
39
|
-
* @return {LH.Config.ResolvedConfig['navigations']}
|
|
40
|
-
*/
|
|
41
|
-
export function filterNavigationsByAvailableArtifacts(navigations: LH.Config.ResolvedConfig['navigations'], availableArtifacts: Array<LH.Config.AnyArtifactDefn>): LH.Config.ResolvedConfig['navigations'];
|
|
42
34
|
/**
|
|
43
35
|
* Filters an array of audits down to the set that can be computed using only the specified artifacts.
|
|
44
36
|
*
|
package/core/config/filters.js
CHANGED
|
@@ -107,30 +107,6 @@ function filterArtifactsByGatherMode(artifacts, mode) {
|
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
/**
|
|
111
|
-
* Filters an array of navigations down to the set supported by the available artifacts.
|
|
112
|
-
*
|
|
113
|
-
* @param {LH.Config.ResolvedConfig['navigations']} navigations
|
|
114
|
-
* @param {Array<LH.Config.AnyArtifactDefn>} availableArtifacts
|
|
115
|
-
* @return {LH.Config.ResolvedConfig['navigations']}
|
|
116
|
-
*/
|
|
117
|
-
function filterNavigationsByAvailableArtifacts(navigations, availableArtifacts) {
|
|
118
|
-
if (!navigations) return navigations;
|
|
119
|
-
|
|
120
|
-
const availableArtifactIds = new Set(
|
|
121
|
-
availableArtifacts.map(artifact => artifact.id).concat(baseArtifactKeys)
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
return navigations
|
|
125
|
-
.map(navigation => {
|
|
126
|
-
return {
|
|
127
|
-
...navigation,
|
|
128
|
-
artifacts: navigation.artifacts.filter((artifact) => availableArtifactIds.has(artifact.id)),
|
|
129
|
-
};
|
|
130
|
-
})
|
|
131
|
-
.filter(navigation => navigation.artifacts.length);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
110
|
/**
|
|
135
111
|
* Filters an array of audits down to the set that can be computed using only the specified artifacts.
|
|
136
112
|
*
|
|
@@ -318,13 +294,10 @@ function filterConfigByExplicitFilters(resolvedConfig, filters) {
|
|
|
318
294
|
if (artifacts && resolvedConfig.settings.disableFullPageScreenshot) {
|
|
319
295
|
artifacts = artifacts.filter(({id}) => id !== 'FullPageScreenshot');
|
|
320
296
|
}
|
|
321
|
-
const navigations =
|
|
322
|
-
filterNavigationsByAvailableArtifacts(resolvedConfig.navigations, artifacts || []);
|
|
323
297
|
|
|
324
298
|
return {
|
|
325
299
|
...resolvedConfig,
|
|
326
300
|
artifacts,
|
|
327
|
-
navigations,
|
|
328
301
|
audits,
|
|
329
302
|
categories,
|
|
330
303
|
};
|
|
@@ -335,7 +308,6 @@ export {
|
|
|
335
308
|
filterConfigByExplicitFilters,
|
|
336
309
|
filterArtifactsByGatherMode,
|
|
337
310
|
filterArtifactsByAvailableAudits,
|
|
338
|
-
filterNavigationsByAvailableArtifacts,
|
|
339
311
|
filterAuditsByAvailableArtifacts,
|
|
340
312
|
filterAuditsByGatherMode,
|
|
341
313
|
filterCategoriesByAvailableAudits,
|
|
@@ -19,14 +19,6 @@ export function assertValidPluginName(config: LH.Config, pluginName: string): vo
|
|
|
19
19
|
* @param {LH.Config.AnyArtifactDefn} artifactDefn
|
|
20
20
|
*/
|
|
21
21
|
export function assertValidArtifact(artifactDefn: LH.Config.AnyArtifactDefn): void;
|
|
22
|
-
/**
|
|
23
|
-
* Throws an error if the provided object does not implement the required navigations interface.
|
|
24
|
-
* @param {LH.Config.ResolvedConfig['navigations']} navigationsDefn
|
|
25
|
-
* @return {{warnings: string[]}}
|
|
26
|
-
*/
|
|
27
|
-
export function assertValidNavigations(navigationsDefn: LH.Config.ResolvedConfig['navigations']): {
|
|
28
|
-
warnings: string[];
|
|
29
|
-
};
|
|
30
22
|
/**
|
|
31
23
|
* Throws an error if the provided object does not implement the required properties of an audit
|
|
32
24
|
* definition.
|
|
@@ -45,18 +37,15 @@ export function assertValidCategories(categories: LH.Config.ResolvedConfig['cate
|
|
|
45
37
|
*/
|
|
46
38
|
export function assertValidSettings(settings: LH.Config.Settings): void;
|
|
47
39
|
/**
|
|
48
|
-
* Asserts that artifacts are in a
|
|
40
|
+
* Asserts that artifacts are unique, valid and are in a dependency order that can be computed.
|
|
49
41
|
*
|
|
50
|
-
* @param {Array<LH.Config.
|
|
42
|
+
* @param {Array<LH.Config.AnyArtifactDefn>} artifactDefns
|
|
51
43
|
*/
|
|
52
|
-
export function
|
|
44
|
+
export function assertValidArtifacts(artifactDefns: Array<LH.Config.AnyArtifactDefn>): void;
|
|
53
45
|
/**
|
|
54
46
|
* @param {LH.Config.ResolvedConfig} resolvedConfig
|
|
55
|
-
* @return {{warnings: string[]}}
|
|
56
47
|
*/
|
|
57
|
-
export function assertValidConfig(resolvedConfig: LH.Config.ResolvedConfig):
|
|
58
|
-
warnings: string[];
|
|
59
|
-
};
|
|
48
|
+
export function assertValidConfig(resolvedConfig: LH.Config.ResolvedConfig): void;
|
|
60
49
|
/**
|
|
61
50
|
* @param {string} artifactId
|
|
62
51
|
* @param {string} dependencyKey
|