Skip to content

Commit

Permalink
Revamp of the offline.js gatherer
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffposnick authored and brendankenny committed Aug 30, 2016
1 parent ee92529 commit 2b39d27
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 51 deletions.
1 change: 1 addition & 0 deletions lighthouse-core/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
},
{
"loadPage": true,
"network": true,
"gatherers": [
"service-worker",
"offline"
Expand Down
52 changes: 20 additions & 32 deletions lighthouse-core/gather/gatherers/offline.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,10 @@
* limitations under the License.
*/

/* global XMLHttpRequest, __returnResults */

'use strict';

const Gatherer = require('./gatherer');

// *WARNING* do not use fetch.. due to it requiring window focus to fire.
// Request the current page by issuing a XMLHttpRequest request to ''
// and storing the status code on the window.
// This runs in the context of the page, so we don't cover it with unit tests.
/* istanbul ignore next */
const requestPage = function() {
const oReq = new XMLHttpRequest();
oReq.onload = oReq.onerror = e => {
// __returnResults is injected by driver.evaluateAsync
__returnResults(e.currentTarget.status);
};
oReq.open('GET', '');
oReq.send();
};

class Offline extends Gatherer {

static config(opts) {
Expand All @@ -59,23 +42,28 @@ class Offline extends Gatherer {
return driver.sendCommand('Network.emulateNetworkConditions', Offline.config({offline: false}));
}

afterPass(options) {
beforePass(options) {
const driver = options.driver;

// TODO eventually we will want to walk all network
// requests that the page initially made and retry them.
return Offline
.goOffline(driver)
.then(_ => driver.evaluateAsync(`(${requestPage.toString()}())`))
.then(offlineResponseCode => {
this.artifact = offlineResponseCode;
})
.then(_ => Offline.goOnline(driver))
.catch(_ => {
this.artifact = {
offlineResponseCode: -1
};
});
return driver.gotoURL(options.url, {waitForLoad: true})
.then(_ => Offline.goOffline(driver))
// Navigate away, then back, to allow a service worker that doesn't call
// clients.claim() to take control of the page load.
.then(_ => driver.gotoURL('about:blank'))
.then(_ => driver.gotoURL(options.url, {waitForLoad: true}))
.then(_ => Offline.goOnline(driver));
}

afterPass(options, tracingData) {
const navigationRecord = tracingData.networkRecords.filter(record => {
// If options.url is just an origin without a path, the Chrome will
// implicitly add in a path of '/'.
return (record._url === options.url || record._url === options.url + '/') &&
record._initiator.type === 'other' &&
record._fetchedViaServiceWorker;
})[0];

this.artifact = navigationRecord ? navigationRecord.statusCode : -1;
}
}

Expand Down
10 changes: 8 additions & 2 deletions lighthouse-core/lib/network-recorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,14 @@ class NetworkRecorder extends EventEmitter {
}

onResourceChangedPriority(data) {
this.networkManager._dispatcher.resourceChangedPriority(data.requestId,
data.newPriority, data.timestamp);
// TODO: this.networkManager._dispatcher.resourceChangedPriority is set to
// undefined when onResourceChangedPriority is triggered in
// gatherers/offline.js. The underlying cause may need to be investigated.
// In the meantime, explicitly check that it's a function.
if (typeof this.networkManager._dispatcher.resourceChangedPriority === 'function') {
this.networkManager._dispatcher.resourceChangedPriority(data.requestId,
data.newPriority, data.timestamp);
}
}

static recordsFromLogs(logs) {
Expand Down
17 changes: 0 additions & 17 deletions lighthouse-core/test/gather/gatherers/offline-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,4 @@ describe('HTTP Redirect gatherer', () => {
assert.deepEqual(offlineGather.artifact, {offlineResponseCode: -1});
});
});

it('handles driver evaluateAsync() failure', () => {
return offlineGather.afterPass({
driver: {
sendCommand() {
return Promise.resolve();
},
evaluateAsync() {
return Promise.reject();
}
}
}).then(_ => {
assert(false);
}).catch(_ => {
assert.deepEqual(offlineGather.artifact, {offlineResponseCode: -1});
});
});
});

0 comments on commit 2b39d27

Please sign in to comment.