fix(chromium): make interception work with dedicated workers (#4658)
This commit is contained in:
parent
b9c959768c
commit
495085cbb2
|
|
@ -200,6 +200,11 @@ export class CRNetworkManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let frame = requestWillBeSentEvent.frameId ? this._page._frameManager.frame(requestWillBeSentEvent.frameId) : workerFrame;
|
let frame = requestWillBeSentEvent.frameId ? this._page._frameManager.frame(requestWillBeSentEvent.frameId) : workerFrame;
|
||||||
|
// Requests from workers lack frameId, because we receive Network.requestWillBeSent
|
||||||
|
// on the worker target. However, we receive Fetch.requestPaused on the page target,
|
||||||
|
// and lack workerFrame there. Luckily, Fetch.requestPaused provides a frameId.
|
||||||
|
if (!frame && requestPausedEvent && requestPausedEvent.frameId)
|
||||||
|
frame = this._page._frameManager.frame(requestPausedEvent.frameId);
|
||||||
|
|
||||||
// Check if it's main resource request interception (targetId === main frame id).
|
// Check if it's main resource request interception (targetId === main frame id).
|
||||||
if (!frame && requestPausedEvent && requestWillBeSentEvent.frameId === (this._page._delegate as CRPage)._targetId) {
|
if (!frame && requestPausedEvent && requestWillBeSentEvent.frameId === (this._page._delegate as CRPage)._targetId) {
|
||||||
|
|
@ -209,11 +214,12 @@ export class CRNetworkManager {
|
||||||
frame = this._page._frameManager.frameAttached(requestWillBeSentEvent.frameId, null);
|
frame = this._page._frameManager.frameAttached(requestWillBeSentEvent.frameId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frame) {
|
// CORS options request is generated by the network stack. If interception is enabled,
|
||||||
if (requestPausedEvent) {
|
// we accept all CORS options, assuming that this was intended when setting route.
|
||||||
// CORS options request is generated by the network stack, it is not associated with the frame id.
|
//
|
||||||
// If URL matches interception pattern, accept it, assuming that this was intended when setting route.
|
// Note: it would be better to match the URL against interception patterns, but
|
||||||
if (requestPausedEvent.request.method === 'OPTIONS' && this._page._needsRequestInterception()) {
|
// that information is only available to the client. Perhaps we can just route to the client?
|
||||||
|
if (requestPausedEvent && requestPausedEvent.request.method === 'OPTIONS' && this._page._needsRequestInterception()) {
|
||||||
const requestHeaders = requestPausedEvent.request.headers;
|
const requestHeaders = requestPausedEvent.request.headers;
|
||||||
const responseHeaders: Protocol.Fetch.HeaderEntry[] = [
|
const responseHeaders: Protocol.Fetch.HeaderEntry[] = [
|
||||||
{ name: 'Access-Control-Allow-Origin', value: requestHeaders['Origin'] || '*' },
|
{ name: 'Access-Control-Allow-Origin', value: requestHeaders['Origin'] || '*' },
|
||||||
|
|
@ -229,12 +235,15 @@ export class CRNetworkManager {
|
||||||
responseHeaders,
|
responseHeaders,
|
||||||
body: '',
|
body: '',
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
this._client._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!frame) {
|
||||||
|
if (requestPausedEvent)
|
||||||
|
this._client._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let allowInterception = this._userRequestInterceptionEnabled;
|
let allowInterception = this._userRequestInterceptionEnabled;
|
||||||
if (redirectedFrom) {
|
if (redirectedFrom) {
|
||||||
allowInterception = false;
|
allowInterception = false;
|
||||||
|
|
|
||||||
|
|
@ -88,18 +88,15 @@ it('should work with glob', async () => {
|
||||||
expect(globToRegex('**/*.{png,jpg,jpeg}').test('https://localhost:8080/c.css')).toBeFalsy();
|
expect(globToRegex('**/*.{png,jpg,jpeg}').test('https://localhost:8080/c.css')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should intercept network activity from worker', (test, {browserName}) => {
|
it('should intercept network activity from worker', async function({page, server}) {
|
||||||
// @see https://github.com/microsoft/playwright/issues/4487
|
|
||||||
test.fixme(browserName === 'chromium');
|
|
||||||
}, async function({page, server}) {
|
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
server.setRoute('/data_for_worker', (req, res) => res.end('failed to intercept'));
|
server.setRoute('/data_for_worker', (req, res) => res.end('failed to intercept'));
|
||||||
const url = server.PREFIX + '/data_for_worker';
|
const url = server.PREFIX + '/data_for_worker';
|
||||||
page.route(url, async route => {
|
await page.route(url, route => {
|
||||||
await route.fulfill({
|
route.fulfill({
|
||||||
status: 200,
|
status: 200,
|
||||||
body: 'intercepted',
|
body: 'intercepted',
|
||||||
});
|
}).catch(e => null);
|
||||||
});
|
});
|
||||||
const [msg] = await Promise.all([
|
const [msg] = await Promise.all([
|
||||||
page.waitForEvent('console'),
|
page.waitForEvent('console'),
|
||||||
|
|
@ -110,6 +107,22 @@ it('should intercept network activity from worker', (test, {browserName}) => {
|
||||||
expect(msg.text()).toBe('intercepted');
|
expect(msg.text()).toBe('intercepted');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should intercept network activity from worker', async function({page, server}) {
|
||||||
|
const url = server.PREFIX + '/worker/worker.js';
|
||||||
|
await page.route(url, route => {
|
||||||
|
route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
body: 'console.log("intercepted");',
|
||||||
|
contentType: 'application/javascript',
|
||||||
|
}).catch(e => null);
|
||||||
|
});
|
||||||
|
const [msg] = await Promise.all([
|
||||||
|
page.waitForEvent('console'),
|
||||||
|
page.goto(server.PREFIX + '/worker/worker.html'),
|
||||||
|
]);
|
||||||
|
expect(msg.text()).toBe('intercepted');
|
||||||
|
});
|
||||||
|
|
||||||
it('should work with regular expression passed from a different context', async ({page, server}) => {
|
it('should work with regular expression passed from a different context', async ({page, server}) => {
|
||||||
const ctx = vm.createContext();
|
const ctx = vm.createContext();
|
||||||
const regexp = vm.runInContext('new RegExp("empty\\.html")', ctx);
|
const regexp = vm.runInContext('new RegExp("empty\\.html")', ctx);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue