fix(firefox): partially implement setOfflineMode using interception

This commit is contained in:
Dmitry Gozman 2020-02-13 15:14:17 -08:00
parent 25022e4685
commit d250f74e4e
4 changed files with 26 additions and 7 deletions

View file

@ -28,6 +28,8 @@ export class FFNetworkManager {
private _requests: Map<string, InterceptableRequest>;
private _page: Page;
private _eventListeners: RegisteredListener[];
private _userInterceptionEnabled = false;
private _offlineModeEnabled = false;
constructor(session: FFSession, page: Page) {
this._session = session;
@ -48,6 +50,17 @@ export class FFNetworkManager {
}
async setRequestInterception(enabled: boolean) {
this._userInterceptionEnabled = enabled;
await this._updateProtocolInterception();
}
async setOfflineMode(enabled: boolean) {
this._offlineModeEnabled = enabled;
await this._updateProtocolInterception();
}
async _updateProtocolInterception() {
const enabled = this._userInterceptionEnabled || this._offlineModeEnabled;
await this._session.send('Network.setRequestInterception', {enabled});
}
@ -62,9 +75,15 @@ export class FFNetworkManager {
redirectChain.push(redirected.request);
this._requests.delete(redirected._id);
}
const request = new InterceptableRequest(this._session, frame, redirectChain, event);
const request = new InterceptableRequest(this._session, frame, redirectChain, event, event.isIntercepted && this._userInterceptionEnabled);
this._requests.set(request._id, request);
this._page._frameManager.requestStarted(request.request);
if (event.isIntercepted && !this._userInterceptionEnabled) {
if (this._offlineModeEnabled)
request.abort('internetdisconnected');
else
request.continue({});
}
}
_onResponseReceived(event: Protocol.Network.responseReceivedPayload) {
@ -146,7 +165,7 @@ class InterceptableRequest implements network.RequestDelegate {
_id: string;
private _session: FFSession;
constructor(session: FFSession, frame: frames.Frame, redirectChain: network.Request[], payload: Protocol.Network.requestWillBeSentPayload) {
constructor(session: FFSession, frame: frames.Frame, redirectChain: network.Request[], payload: Protocol.Network.requestWillBeSentPayload, isIntercepted: boolean) {
this._id = payload.requestId;
this._session = session;
@ -154,7 +173,7 @@ class InterceptableRequest implements network.RequestDelegate {
for (const {name, value} of payload.headers)
headers[name.toLowerCase()] = value;
this.request = new network.Request(payload.isIntercepted ? this : null, frame, redirectChain, payload.navigationId,
this.request = new network.Request(isIntercepted ? this : null, frame, redirectChain, payload.navigationId,
payload.url, causeToResourceType[payload.cause] || 'other', payload.method, payload.postData, headers);
}

View file

@ -284,7 +284,7 @@ export class FFPage implements PageDelegate {
}
async setOfflineMode(enabled: boolean): Promise<void> {
throw new Error('Offline mode not implemented in Firefox');
await this._networkManager.setOfflineMode(enabled);
}
async authenticate(credentials: types.Credentials | null): Promise<void> {

View file

@ -521,7 +521,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
});
});
describe.skip(FFOX)('Interception.setOfflineMode', function() {
describe('Interception.setOfflineMode', function() {
it('should work', async({page, server}) => {
await page.setOfflineMode(true);
let error = null;
@ -531,7 +531,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
const response = await page.goto(server.EMPTY_PAGE);
expect(response.status()).toBe(200);
});
it('should emulate navigator.onLine', async({page, server}) => {
it.skip(FFOX)('should emulate navigator.onLine', async({page, server}) => {
expect(await page.evaluate(() => window.navigator.onLine)).toBe(true);
await page.setOfflineMode(true);
expect(await page.evaluate(() => window.navigator.onLine)).toBe(false);

View file

@ -87,7 +87,7 @@ if (process.env.BROWSER === 'firefox') {
...require('../lib/events').Events,
...require('../lib/chromium/events').Events,
};
missingCoverage = ['browserContext.setGeolocation', 'elementHandle.scrollIntoViewIfNeeded', 'page.setOfflineMode'];
missingCoverage = ['browserContext.setGeolocation', 'elementHandle.scrollIntoViewIfNeeded'];
} else if (process.env.BROWSER === 'webkit') {
product = 'WebKit';
events = require('../lib/events').Events;