fix(webkit): use cross-process loader ids (#484)

This commit is contained in:
Yury Semikhatsky 2020-01-14 09:48:36 -08:00 committed by GitHub
parent fb1b3d9a89
commit d341b43023
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 64 additions and 16 deletions

View File

@ -10,7 +10,7 @@
"playwright": {
"chromium_revision": "724623",
"firefox_revision": "1011",
"webkit_revision": "1084"
"webkit_revision": "1087"
},
"scripts": {
"unit": "node test/test.js",

View File

@ -188,6 +188,7 @@ export class FFPage implements PageDelegate {
}
async navigateFrame(frame: frames.Frame, url: string, referer: string | undefined): Promise<frames.GotoResult> {
this._page._validateNavigationReferrer(referer);
const response = await this._session.send('Page.navigate', { url, referer, frameId: frame._id });
return { newDocumentId: response.navigationId || undefined, isSameDocument: !response.navigationId };
}

View File

@ -219,6 +219,11 @@ export class FrameManager {
this._page.emit(Events.Page.RequestFailed, request);
}
provisionalLoadFailed(documentId: string, error: string) {
for (const watcher of this._lifecycleWatchers)
watcher._onProvisionalLoadFailed(documentId, error);
}
private _removeFramesRecursively(frame: Frame) {
for (const child of frame.childFrames())
this._removeFramesRecursively(child);
@ -973,6 +978,10 @@ class LifecycleWatcher {
}
}
_onProvisionalLoadFailed(documentId: string, error: string) {
this._onAbortedNewDocumentNavigation(this._frame, documentId, error);
}
_onLifecycleEvent(frame: Frame) {
this._checkLifecycleComplete();
}

View File

@ -171,6 +171,18 @@ export class Page extends platform.EventEmitter {
this.emit(Events.Page.FileChooser, fileChooser);
}
_validateNavigationReferrer(referrer: string | undefined) {
if (!referrer)
return;
if (!this._state.extraHTTPHeaders)
return;
const header = this._state.extraHTTPHeaders['referer'];
if (!header)
return;
if (header !== referrer)
throw new Error('"referer" is already specified as extra HTTP header');
}
browserContext(): BrowserContext {
return this._browserContext;
}

View File

@ -62,6 +62,7 @@ export class WKBrowser extends platform.EventEmitter implements Browser {
this._eventListeners = [
helper.addEventListener(this._browserSession, 'Browser.pageProxyCreated', this._onPageProxyCreated.bind(this)),
helper.addEventListener(this._browserSession, 'Browser.pageProxyDestroyed', this._onPageProxyDestroyed.bind(this)),
helper.addEventListener(this._browserSession, 'Browser.provisionalLoadFailed', event => this._onProvisionalLoadFailed(event)),
helper.addEventListener(this._browserSession, kPageProxyMessageReceived, this._onPageProxyMessageReceived.bind(this)),
];
@ -142,6 +143,11 @@ export class WKBrowser extends platform.EventEmitter implements Browser {
pageProxy.dispatchMessageToSession(event.message);
}
_onProvisionalLoadFailed(event: Protocol.Browser.provisionalLoadFailedPayload) {
const pageProxy = this._pageProxies.get(event.pageProxyId)!;
pageProxy.handleProvisionalLoadFailed(event);
}
disconnect() {
throw new Error('Unsupported operation');
}

View File

@ -223,8 +223,12 @@ export class WKPage implements PageDelegate {
}
async navigateFrame(frame: frames.Frame, url: string, referrer: string | undefined): Promise<frames.GotoResult> {
await this._session.send('Page.navigate', { url, frameId: frame._id, referrer });
return {}; // We cannot get loaderId of cross-process navigation in advance.
this._page._validateNavigationReferrer(referrer);
if (this._pageProxySession.isDisposed())
throw new Error('Target closed');
const pageProxyId = this._pageProxySession.sessionId;
const result = await this._pageProxySession.connection!.browserSession.send('Browser.navigate', { url, pageProxyId, frameId: frame._id, referrer });
return { newDocumentId: result.loaderId, isSameDocument: !result.loaderId };
}
needsLifecycleResetOnSetContent(): boolean {

View File

@ -64,6 +64,12 @@ export class WKPageProxy {
this._pageProxySession.dispatchMessage(message);
}
handleProvisionalLoadFailed(event: Protocol.Browser.provisionalLoadFailedPayload) {
if (!this._wkPage)
return;
this._wkPage._page._frameManager.provisionalLoadFailed(event.loaderId, event.error);
}
async page(): Promise<Page> {
if (!this._pagePromise)
this._pagePromise = this._initializeWKPage();

View File

@ -158,7 +158,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
await page.goto(httpsServer.PREFIX + '/redirect/1.html').catch(e => error = e);
expectSSLError(error.message);
});
it.skip(WEBKIT)('should not crash when navigating to bad SSL after a cross origin navigation', async({page, server, httpsServer}) => {
it('should not crash when navigating to bad SSL after a cross origin navigation', async({page, server, httpsServer}) => {
await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html');
await page.goto(httpsServer.EMPTY_PAGE).catch(e => void 0);
});
@ -322,19 +322,26 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
expect(request2.headers['referer']).toBe(server.PREFIX + '/grid.html');
expect(page.url()).toBe(server.PREFIX + '/grid.html');
});
it.skip(FFOX)('should use referer option when setExtraHTTPHeaders provides referer', async({page, server}) => {
it('should use referer option when setExtraHTTPHeaders provides referer', async({page, server}) => {
await page.setExtraHTTPHeaders({ 'referer': 'http://microsoft.com/' });
const [request1, request2] = await Promise.all([
server.waitForRequest('/grid.html'),
server.waitForRequest('/digits/1.png'),
page.goto(server.PREFIX + '/grid.html', {
referer: 'http://google.com/',
}),
]);
expect(request1.headers['referer']).toBe('http://google.com/');
// Make sure subresources use referer specified by setExtraHTTPHeaders.
expect(request2.headers['referer']).toBe('http://microsoft.com/');
expect(page.url()).toBe(server.PREFIX + '/grid.html');
try {
const [request1, request2] = await Promise.all([
server.waitForRequest('/grid.html'),
server.waitForRequest('/digits/1.png'),
page.goto(server.PREFIX + '/grid.html', {
referer: 'http://google.com/',
}),
]);
expect(request1.headers['referer']).toBe('http://google.com/');
// Make sure subresources use referer specified by setExtraHTTPHeaders.
expect(request2.headers['referer']).toBe('http://microsoft.com/');
expect(page.url()).toBe(server.PREFIX + '/grid.html');
} catch (error) {
if (FFOX || WEBKIT)
expect(error.message).toBe('"referer" is already specified as extra HTTP header');
else
throw error;
}
});
it('should override referrer-policy', async({page, server}) => {
server.setRoute('/grid.html', (req, res) => {

View File

@ -781,6 +781,9 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF
describe('Page.setCacheEnabled', function() {
it('should enable or disable the cache based on the state passed', async({page, server}) => {
await page.goto(server.PREFIX + '/cached/one-style.html');
// WebKit does r.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
// when navigating to the same url, load empty.html to avoid that.
await page.goto(server.EMPTY_PAGE);
const [cachedRequest] = await Promise.all([
server.waitForRequest('/cached/one-style.html'),
page.goto(server.PREFIX + '/cached/one-style.html'),