feat(firefox): support request interception (#571)
This commit is contained in:
parent
68d51a371e
commit
23a668e3be
|
|
@ -9,7 +9,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"playwright": {
|
"playwright": {
|
||||||
"chromium_revision": "733125",
|
"chromium_revision": "733125",
|
||||||
"firefox_revision": "1016",
|
"firefox_revision": "1017",
|
||||||
"webkit_revision": "1106"
|
"webkit_revision": "1106"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ class InterceptableRequest implements network.RequestDelegate {
|
||||||
for (const {name, value} of payload.headers)
|
for (const {name, value} of payload.headers)
|
||||||
headers[name.toLowerCase()] = value;
|
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);
|
payload.url, causeToResourceType[payload.cause] || 'other', payload.method, payload.postData, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,23 +163,53 @@ class InterceptableRequest implements network.RequestDelegate {
|
||||||
const {
|
const {
|
||||||
headers,
|
headers,
|
||||||
} = overrides;
|
} = overrides;
|
||||||
await this._session.send('Network.resumeSuspendedRequest', {
|
await this._session.send('Network.resumeInterceptedRequest', {
|
||||||
requestId: this._id,
|
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 => {
|
}).catch(error => {
|
||||||
debugError(error);
|
debugError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fulfill(response: { status: number; headers: network.Headers; contentType: string; body: (string | platform.BufferType); }) {
|
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() {
|
async abort(errorCode: string) {
|
||||||
await this._session.send('Network.abortSuspendedRequest', {
|
await this._session.send('Network.abortInterceptedRequest', {
|
||||||
requestId: this._id,
|
requestId: this._id,
|
||||||
|
errorCode,
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
debugError(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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -294,8 +294,8 @@ export class FFPage implements PageDelegate {
|
||||||
throw new Error('Offline mode not implemented in Firefox');
|
throw new Error('Offline mode not implemented in Firefox');
|
||||||
}
|
}
|
||||||
|
|
||||||
async authenticate(credentials: types.Credentials): Promise<void> {
|
async authenticate(credentials: types.Credentials | null): Promise<void> {
|
||||||
throw new Error('Offline mode not implemented in Firefox');
|
await this._session.send('Network.setAuthCredentials', credentials || { username: null, password: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
async reload(): Promise<void> {
|
async reload(): Promise<void> {
|
||||||
|
|
|
||||||
BIN
test/golden-firefox/mock-binary-response.png
Normal file
BIN
test/golden-firefox/mock-binary-response.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
|
|
@ -178,7 +178,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
if (WEBKIT)
|
if (WEBKIT)
|
||||||
expect(failedRequest.failure().errorText).toBe('Request intercepted');
|
expect(failedRequest.failure().errorText).toBe('Request intercepted');
|
||||||
else if (FFOX)
|
else if (FFOX)
|
||||||
expect(failedRequest.failure().errorText).toBe('NS_ERROR_FAILURE');
|
expect(failedRequest.failure().errorText).toBe('NS_ERROR_OFFLINE');
|
||||||
else
|
else
|
||||||
expect(failedRequest.failure().errorText).toBe('net::ERR_INTERNET_DISCONNECTED');
|
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}) => {
|
it('should work', async({page, server}) => {
|
||||||
await page.setRequestInterception(true);
|
await page.setRequestInterception(true);
|
||||||
page.on('request', request => {
|
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}) => {
|
it('should work', async({page, server}) => {
|
||||||
server.setAuth('/empty.html', 'user', 'pass');
|
server.setAuth('/empty.html', 'user', 'pass');
|
||||||
let response = await page.goto(server.EMPTY_PAGE);
|
let response = await page.goto(server.EMPTY_PAGE);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue