feat(firefox): support request interception (#571)

This commit is contained in:
Dmitry Gozman 2020-01-23 10:38:28 -08:00 committed by GitHub
parent 68d51a371e
commit 23a668e3be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 12 deletions

View file

@ -9,7 +9,7 @@
"main": "index.js",
"playwright": {
"chromium_revision": "733125",
"firefox_revision": "1016",
"firefox_revision": "1017",
"webkit_revision": "1106"
},
"scripts": {

View file

@ -155,7 +155,7 @@ class InterceptableRequest implements network.RequestDelegate {
for (const {name, value} of payload.headers)
headers[name.toLowerCase()] = value;
this.request = new network.Request(payload.suspended ? this : null, frame, redirectChain, payload.navigationId,
this.request = new network.Request(payload.isIntercepted ? this : null, frame, redirectChain, payload.navigationId,
payload.url, causeToResourceType[payload.cause] || 'other', payload.method, payload.postData, headers);
}
@ -163,23 +163,53 @@ class InterceptableRequest implements network.RequestDelegate {
const {
headers,
} = overrides;
await this._session.send('Network.resumeSuspendedRequest', {
await this._session.send('Network.resumeInterceptedRequest', {
requestId: this._id,
headers: headers ? Object.entries(headers).filter(([, value]) => !Object.is(value, undefined)).map(([name, value]) => ({name, value})) : undefined,
headers: headers ? headersArray(headers) : undefined,
}).catch(error => {
debugError(error);
});
}
async fulfill(response: { status: number; headers: network.Headers; contentType: string; body: (string | platform.BufferType); }) {
throw new Error('Fulfill is not supported in Firefox');
const responseBody = response.body && helper.isString(response.body) ? platform.Buffer.from(response.body) : (response.body || null);
const responseHeaders: { [s: string]: string; } = {};
if (response.headers) {
for (const header of Object.keys(response.headers))
responseHeaders[header.toLowerCase()] = response.headers[header];
}
if (response.contentType)
responseHeaders['content-type'] = response.contentType;
if (responseBody && !('content-length' in responseHeaders))
responseHeaders['content-length'] = String(platform.Buffer.byteLength(responseBody));
await this._session.send('Network.fulfillInterceptedRequest', {
requestId: this._id,
status: response.status || 200,
statusText: network.STATUS_TEXTS[String(response.status || 200)] || '',
headers: headersArray(responseHeaders),
base64body: responseBody ? responseBody.toString('base64') : undefined,
}).catch(error => {
debugError(error);
});
}
async abort() {
await this._session.send('Network.abortSuspendedRequest', {
async abort(errorCode: string) {
await this._session.send('Network.abortInterceptedRequest', {
requestId: this._id,
errorCode,
}).catch(error => {
debugError(error);
});
}
}
function headersArray(headers: network.Headers): Protocol.Network.HTTPHeader[] {
const result: Protocol.Network.HTTPHeader[] = [];
for (const name in headers) {
if (!Object.is(headers[name], undefined))
result.push({name, value: headers[name] + ''});
}
return result;
}

View file

@ -294,8 +294,8 @@ export class FFPage implements PageDelegate {
throw new Error('Offline mode not implemented in Firefox');
}
async authenticate(credentials: types.Credentials): Promise<void> {
throw new Error('Offline mode not implemented in Firefox');
async authenticate(credentials: types.Credentials | null): Promise<void> {
await this._session.send('Network.setAuthCredentials', credentials || { username: null, password: null });
}
async reload(): Promise<void> {

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -178,7 +178,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
if (WEBKIT)
expect(failedRequest.failure().errorText).toBe('Request intercepted');
else if (FFOX)
expect(failedRequest.failure().errorText).toBe('NS_ERROR_FAILURE');
expect(failedRequest.failure().errorText).toBe('NS_ERROR_OFFLINE');
else
expect(failedRequest.failure().errorText).toBe('net::ERR_INTERNET_DISCONNECTED');
});
@ -438,7 +438,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
});
});
describe.skip(FFOX)('interception.fulfill', function() {
describe('interception.fulfill', function() {
it('should work', async({page, server}) => {
await page.setRequestInterception(true);
page.on('request', request => {
@ -506,7 +506,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
});
});
describe.skip(FFOX)('Interception.authenticate', function() {
describe('Page.authenticate', function() {
it('should work', async({page, server}) => {
server.setAuth('/empty.html', 'user', 'pass');
let response = await page.goto(server.EMPTY_PAGE);