Skip to content

Commit 64b015e

Browse files
authored
refactor(StartUrl): switch from error to debugString object (#2549)
* refactor(StartUrl): switch from error to debugString object * feedback * allow debugString during passing * fix test * pre-existing bug fix * more feedback * more more feedback
1 parent 41df647 commit 64b015e

File tree

9 files changed

+99
-72
lines changed

9 files changed

+99
-72
lines changed

lighthouse-core/audits/multi-check-audit.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,16 @@ class MultiCheckAudit extends Audit {
3838
};
3939
}
4040

41+
let debugString;
42+
if (result.warnings && result.warnings.length > 0) {
43+
debugString = `Warnings: ${result.warnings.join(', ')}`;
44+
}
45+
4146
// Otherwise, we pass
4247
return {
4348
rawValue: true,
44-
extendedInfo
49+
extendedInfo,
50+
debugString,
4551
};
4652
}
4753

lighthouse-core/audits/webapp-install-banner.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ class WebappInstallBanner extends MultiCheckAudit {
4646
};
4747
}
4848

49-
static assessManifest(manifestValues, failures) {
49+
static assessManifest(artifacts, result) {
50+
const {manifestValues, failures} = result;
5051
if (manifestValues.isParseFailure) {
5152
failures.push(manifestValues.parseFailureReason);
5253
return;
@@ -69,32 +70,36 @@ class WebappInstallBanner extends MultiCheckAudit {
6970
}
7071

7172

72-
static assessServiceWorker(artifacts, failures) {
73+
static assessServiceWorker(artifacts, result) {
7374
const hasServiceWorker = SWAudit.audit(artifacts).rawValue;
7475
if (!hasServiceWorker) {
75-
failures.push('Site does not register a Service Worker');
76+
result.failures.push('Site does not register a Service Worker');
7677
}
7778
}
7879

79-
static assessOfflineStartUrl(artifacts, failures) {
80-
const hasOfflineStartUrl = artifacts.StartUrl === 200;
80+
static assessOfflineStartUrl(artifacts, result) {
81+
const hasOfflineStartUrl = artifacts.StartUrl.statusCode === 200;
82+
8183
if (!hasOfflineStartUrl) {
82-
failures.push('Manifest start_url is not cached by a Service Worker');
84+
result.failures.push('Manifest start_url is not cached by a Service Worker');
85+
}
86+
87+
if (artifacts.StartUrl.debugString) {
88+
result.warnings.push(artifacts.StartUrl.debugString);
8389
}
8490
}
8591

8692
static audit_(artifacts) {
8793
const failures = [];
94+
const warnings = [];
8895

8996
return artifacts.requestManifestValues(artifacts.Manifest).then(manifestValues => {
90-
WebappInstallBanner.assessManifest(manifestValues, failures);
91-
WebappInstallBanner.assessServiceWorker(artifacts, failures);
92-
WebappInstallBanner.assessOfflineStartUrl(artifacts, failures);
93-
94-
return {
95-
failures,
96-
manifestValues
97-
};
97+
const result = {warnings, failures, manifestValues};
98+
WebappInstallBanner.assessManifest(artifacts, result);
99+
WebappInstallBanner.assessServiceWorker(artifacts, result);
100+
WebappInstallBanner.assessOfflineStartUrl(artifacts, result);
101+
102+
return result;
98103
});
99104
}
100105
}

lighthouse-core/gather/driver.js

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -265,25 +265,18 @@ class Driver {
265265
}
266266

267267
getAppManifest() {
268-
return new Promise((resolve, reject) => {
269-
this.sendCommand('Page.getAppManifest')
270-
.then(response => {
271-
// We're not reading `response.errors` however it may contain critical and noncritical
272-
// errors from Blink's manifest parser:
273-
// https://chromedevtools.github.io/debugger-protocol-viewer/tot/Page/#type-AppManifestError
274-
if (!response.data) {
275-
if (response.url) {
276-
return reject(new Error(`Unable to retrieve manifest at ${response.url}.`));
277-
}
278-
279-
// If both the data and the url are empty strings, the page had no manifest.
280-
return reject('No web app manifest found.');
281-
}
268+
return this.sendCommand('Page.getAppManifest')
269+
.then(response => {
270+
// We're not reading `response.errors` however it may contain critical and noncritical
271+
// errors from Blink's manifest parser:
272+
// https://chromedevtools.github.io/debugger-protocol-viewer/tot/Page/#type-AppManifestError
273+
if (!response.data) {
274+
// If the data is empty, the page had no manifest.
275+
return null;
276+
}
282277

283-
resolve(response);
284-
})
285-
.catch(err => reject(err));
286-
});
278+
return response;
279+
});
287280
}
288281

289282
getSecurityState() {

lighthouse-core/gather/gatherers/manifest.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,16 @@ class Manifest extends Gatherer {
2727
afterPass(options) {
2828
return options.driver.getAppManifest()
2929
.then(response => {
30+
if (!response) {
31+
return null;
32+
}
33+
3034
const isBomEncoded = response.data.charCodeAt(0) === BOM_FIRSTCHAR;
3135
if (isBomEncoded) {
3236
response.data = Buffer.from(response.data).slice(BOM_LENGTH).toString();
3337
}
3438

3539
return manifestParser(response.data, response.url, options.url);
36-
})
37-
.catch(err => {
38-
if (err === 'No web app manifest found.') {
39-
return null;
40-
}
41-
42-
return Promise.reject(err);
4340
});
4441
}
4542
}

lighthouse-core/gather/gatherers/start-url.js

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,34 +49,54 @@ class StartUrl extends Gatherer {
4949
pass(options) {
5050
return options.driver.getAppManifest()
5151
.then(response => {
52-
return manifestParser(response.data, response.url, options.url);
52+
return response && manifestParser(response.data, response.url, options.url);
5353
})
5454
.then(manifest => {
55-
if (!manifest.value.start_url || !manifest.value.start_url.raw) {
56-
return Promise.reject(new Error(`No web app manifest found on page ${options.url}`));
55+
if (!manifest || !manifest.value) {
56+
const detailedMsg = manifest && manifest.debugString;
57+
this.debugString = detailedMsg ?
58+
`Error fetching web app manifest: ${detailedMsg}` :
59+
`No usable web app manifest found on page ${options.url}`;
60+
return;
5761
}
5862

5963
if (manifest.value.start_url.debugString) {
60-
return Promise.reject(new Error(manifest.value.start_url.debugString));
64+
// Even if the start URL had an error, the browser will still supply a fallback URL.
65+
// Therefore, we only set the debugString here and continue with the fetch.
66+
this.debugString = manifest.value.start_url.debugString;
6167
}
6268

6369
this.startUrl = manifest.value.start_url.value;
64-
}).then(_ => this.executeFetchRequest(options.driver, this.startUrl));
70+
return this.executeFetchRequest(options.driver, this.startUrl);
71+
});
6572
}
6673

6774
afterPass(options, tracingData) {
68-
if (!this.startUrl) {
69-
return Promise.reject(new Error('No start_url found inside the manifest'));
70-
}
71-
7275
const networkRecords = tracingData.networkRecords;
7376
const navigationRecord = networkRecords.filter(record => {
7477
return URL.equalWithExcludedFragments(record._url, this.startUrl) &&
7578
record._fetchedViaServiceWorker;
7679
}).pop(); // Take the last record that matches.
7780

7881
return options.driver.goOnline(options)
79-
.then(_ => navigationRecord ? navigationRecord.statusCode : -1);
82+
.then(_ => {
83+
if (!this.startUrl) {
84+
return {
85+
statusCode: -1,
86+
debugString: this.debugString || 'No start URL to fetch',
87+
};
88+
} else if (!navigationRecord) {
89+
return {
90+
statusCode: -1,
91+
debugString: this.debugString || 'Did not fetch start URL from service worker',
92+
};
93+
} else {
94+
return {
95+
statusCode: navigationRecord.statusCode,
96+
debugString: this.debugString,
97+
};
98+
}
99+
});
80100
}
81101
}
82102

lighthouse-core/lib/url-shim.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ URL.elideDataURI = function elideDataURI(url) {
103103
// Why? Special handling was added by Chrome team to allow a pushState transition between chrome:// pages.
104104
// As a result, the network URL (chrome://chrome/settings/) doesn't match the final document URL (chrome://settings/).
105105
function rewriteChromeInternalUrl(url) {
106-
if (!url.startsWith('chrome://')) return url;
106+
if (!url || !url.startsWith('chrome://')) return url;
107107
return url.replace(/^chrome:\/\/chrome\//, 'chrome://');
108108
}
109109

lighthouse-core/test/audits/webapp-install-banner-test.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function generateMockArtifacts() {
2626
scriptURL: 'https://example.com/sw.js'
2727
}]
2828
},
29-
StartUrl: 200,
29+
StartUrl: {statusCode: 200},
3030
URL: {finalUrl: 'https://example.com'}
3131
}));
3232
const mockArtifacts = Object.assign({}, computedArtifacts, clonedArtifacts);
@@ -128,7 +128,7 @@ describe('PWA: webapp install banner audit', () => {
128128
it('fails if page had no SW', () => {
129129
const artifacts = generateMockArtifacts();
130130
artifacts.ServiceWorker.versions = [];
131-
artifacts.StartUrl = -1;
131+
artifacts.StartUrl = {statusCode: -1};
132132

133133
return WebappInstallBannerAudit.audit(artifacts).then(result => {
134134
assert.strictEqual(result.rawValue, false);
@@ -141,7 +141,7 @@ describe('PWA: webapp install banner audit', () => {
141141

142142
it('fails if start_url is not cached', () => {
143143
const artifacts = generateMockArtifacts();
144-
artifacts.StartUrl = -1;
144+
artifacts.StartUrl = {statusCode: -1};
145145

146146
return WebappInstallBannerAudit.audit(artifacts).then(result => {
147147
assert.strictEqual(result.rawValue, false);
@@ -150,4 +150,14 @@ describe('PWA: webapp install banner audit', () => {
150150
assert.strictEqual(failures.length, 1, failures);
151151
});
152152
});
153+
154+
it('includes debugString from start_url', () => {
155+
const artifacts = generateMockArtifacts();
156+
artifacts.StartUrl = {statusCode: 200, debugString: 'Warning!'};
157+
158+
return WebappInstallBannerAudit.audit(artifacts).then(result => {
159+
assert.strictEqual(result.rawValue, true);
160+
assert.equal(result.debugString, 'Warnings: Warning!');
161+
});
162+
});
153163
});

lighthouse-core/test/gather/gatherers/manifest-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ describe('Manifest gatherer', () => {
9797
return manifestGather.afterPass({
9898
driver: {
9999
getAppManifest() {
100-
return Promise.reject('No web app manifest found.');
100+
return Promise.resolve(null);
101101
}
102102
}
103103
}).then(artifact => {

lighthouse-core/test/gather/gatherers/start-url-test.js

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@ describe('Start-url gatherer', () => {
9090
startUrlGathererWithQueryString.pass(optionsWithQueryString)
9191
.then(_ => startUrlGathererWithQueryString.afterPass(optionsWithQueryString, tracingData))
9292
]).then(([artifact, artifactWithQueryString]) => {
93-
assert.strictEqual(artifact, -1);
94-
assert.strictEqual(artifactWithQueryString, -1);
93+
assert.equal(artifact.statusCode, -1);
94+
assert.ok(artifact.debugString, 'did not set debug string');
95+
assert.equal(artifactWithQueryString.statusCode, -1);
96+
assert.ok(artifactWithQueryString.debugString, 'did not set debug string');
9597
});
9698
});
9799

@@ -113,25 +115,22 @@ describe('Start-url gatherer', () => {
113115
startUrlGathererWithFragment.pass(optionsWithQueryString)
114116
.then(_ => startUrlGathererWithFragment.afterPass(optionsWithQueryString, tracingData))
115117
]).then(([artifact, artifactWithFragment]) => {
116-
assert.strictEqual(artifact, 200);
117-
assert.strictEqual(artifactWithFragment, 200);
118+
assert.equal(artifact.statusCode, 200);
119+
assert.equal(artifactWithFragment.statusCode, 200);
118120
});
119121
});
120122

121-
it('returns an error when manifest cannot be found', () => {
123+
it('returns a debugString when manifest cannot be found', () => {
122124
const startUrlGatherer = new StartUrlGatherer();
123125
const options = {
124126
url: 'https://ifixit-pwa.appspot.com/',
125127
driver: wrapSendCommand(mockDriver, '')
126128
};
127129

128-
startUrlGatherer.pass(options)
130+
return startUrlGatherer.pass(options)
129131
.then(_ => startUrlGatherer.afterPass(options, tracingData))
130-
.then(_ => {
131-
assert.ok(false, 'should fail because manifest is empty');
132-
})
133-
.catch(err => {
134-
assert.strictEqual(err.message, `No web app manifest found on page ${options.url}`);
132+
.then(artifact => {
133+
assert.equal(artifact.debugString, 'ERROR: start_url string empty');
135134
});
136135
});
137136

@@ -142,13 +141,10 @@ describe('Start-url gatherer', () => {
142141
driver: wrapSendCommand(mockDriver, 'https://not-same-origin.com/')
143142
};
144143

145-
startUrlGatherer.pass(options)
144+
return startUrlGatherer.pass(options)
146145
.then(_ => startUrlGatherer.afterPass(options, tracingData))
147-
.then(_ => {
148-
assert.ok(false, 'should fail because origin is not the same');
149-
})
150-
.catch(err => {
151-
assert.strictEqual(err.message, 'ERROR: start_url must be same-origin as document');
146+
.then(artifact => {
147+
assert.equal(artifact.debugString, 'ERROR: start_url must be same-origin as document');
152148
});
153149
});
154150
});

0 commit comments

Comments
 (0)