Skip to content

Commit

Permalink
fix(ownerFrame): correctly handle adopted node usecase (#677)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgozman authored and yury-s committed Jan 27, 2020
1 parent b3cd7a4 commit 541fa95
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 15 deletions.
5 changes: 5 additions & 0 deletions src/browserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { helper } from './helper';

export interface BrowserContextDelegate {
pages(): Promise<Page[]>;
existingPages(): Page[];
newPage(): Promise<Page>;
close(): Promise<void>;

Expand Down Expand Up @@ -69,6 +70,10 @@ export class BrowserContext {
await this.setGeolocation(this._options.geolocation);
}

_existingPages(): Page[] {
return this._delegate.existingPages();
}

async pages(): Promise<Page[]> {
return this._delegate.pages();
}
Expand Down
9 changes: 9 additions & 0 deletions src/chromium/crBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
return pages.filter(page => !!page) as Page[];
},

existingPages: (): Page[] => {
const pages: Page[] = [];
for (const target of this._allTargets()) {
if (target.browserContext() === context && target._crPage)
pages.push(target._crPage.page());
}
return pages;
},

newPage: async (): Promise<Page> => {
const { targetId } = await this._client.send('Target.createTarget', { url: 'about:blank', browserContextId: contextId || undefined });
const target = this._targets.get(targetId)!;
Expand Down
8 changes: 4 additions & 4 deletions src/chromium/crPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ export class CRPage implements PageDelegate {
return this._page._frameManager.frame(nodeInfo.node.frameId);
}

async getOwnerFrame(handle: dom.ElementHandle): Promise<frames.Frame | null> {
async getOwnerFrame(handle: dom.ElementHandle): Promise<string | null> {
// document.documentElement has frameId of the owner frame.
const documentElement = await handle.evaluateHandle(node => {
const doc = node as Document;
Expand All @@ -440,10 +440,10 @@ export class CRPage implements PageDelegate {
const nodeInfo = await this._client.send('DOM.describeNode', {
objectId: remoteObject.objectId
});
const frame = nodeInfo && typeof nodeInfo.node.frameId === 'string' ?
this._page._frameManager.frame(nodeInfo.node.frameId) : null;
const frameId = nodeInfo && typeof nodeInfo.node.frameId === 'string' ?
nodeInfo.node.frameId : null;
await documentElement.dispose();
return frame;
return frameId;
}

isElementHandle(remoteObject: any): boolean {
Expand Down
11 changes: 10 additions & 1 deletion src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,16 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
}

async ownerFrame(): Promise<frames.Frame | null> {
return this._page._delegate.getOwnerFrame(this);
const frameId = await this._page._delegate.getOwnerFrame(this);
if (!frameId)
return null;
const pages = this._page.browserContext()._existingPages();
for (const page of pages) {
const frame = page._frameManager.frame(frameId);
if (frame)
return frame;
}
return null;
}

async contentFrame(): Promise<frames.Frame | null> {
Expand Down
9 changes: 9 additions & 0 deletions src/firefox/ffBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@ export class FFBrowser extends platform.EventEmitter implements Browser {
return pages.filter(page => !!page);
},

existingPages: (): Page[] => {
const pages: Page[] = [];
for (const target of this._allTargets()) {
if (target.browserContext() === context && target._ffPage)
pages.push(target._ffPage._page);
}
return pages;
},

newPage: async (): Promise<Page> => {
const {targetId} = await this._connection.send('Target.newPage', {
browserContextId: browserContextId || undefined
Expand Down
6 changes: 2 additions & 4 deletions src/firefox/ffPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,14 +373,12 @@ export class FFPage implements PageDelegate {
return this._page._frameManager.frame(contentFrameId);
}

async getOwnerFrame(handle: dom.ElementHandle): Promise<frames.Frame | null> {
async getOwnerFrame(handle: dom.ElementHandle): Promise<string | null> {
const { ownerFrameId } = await this._session.send('Page.describeNode', {
frameId: handle._context.frame._id,
objectId: toRemoteObject(handle).objectId!,
});
if (!ownerFrameId)
return null;
return this._page._frameManager.frame(ownerFrameId);
return ownerFrameId || null;
}

isElementHandle(remoteObject: any): boolean {
Expand Down
2 changes: 1 addition & 1 deletion src/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export interface PageDelegate {
isElementHandle(remoteObject: any): boolean;
adoptElementHandle<T extends Node>(handle: dom.ElementHandle<T>, to: dom.FrameExecutionContext): Promise<dom.ElementHandle<T>>;
getContentFrame(handle: dom.ElementHandle): Promise<frames.Frame | null>; // Only called for frame owner elements.
getOwnerFrame(handle: dom.ElementHandle): Promise<frames.Frame | null>;
getOwnerFrame(handle: dom.ElementHandle): Promise<string | null>; // Returns frameId.
getContentQuads(handle: dom.ElementHandle): Promise<types.Quad[] | null>;
layoutViewport(): Promise<{ width: number, height: number }>;
setInputFiles(handle: dom.ElementHandle<HTMLInputElement>, files: types.FilePayload[]): Promise<void>;
Expand Down
12 changes: 12 additions & 0 deletions src/webkit/wkBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ export class WKBrowser extends platform.EventEmitter implements Browser {
return await Promise.all(pageProxies.map(proxy => proxy.page()));
},

existingPages: (): Page[] => {
const pages: Page[] = [];
for (const pageProxy of this._pageProxies.values()) {
if (pageProxy._browserContext !== context)
continue;
const page = pageProxy.existingPage();
if (page)
pages.push(page);
}
return pages;
},

newPage: async (): Promise<Page> => {
const { pageProxyId } = await this._browserSession.send('Browser.createPage', { browserContextId });
const pageProxy = this._pageProxies.get(pageProxyId)!;
Expand Down
6 changes: 2 additions & 4 deletions src/webkit/wkPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,16 +484,14 @@ export class WKPage implements PageDelegate {
return this._page._frameManager.frame(nodeInfo.contentFrameId);
}

async getOwnerFrame(handle: dom.ElementHandle): Promise<frames.Frame | null> {
async getOwnerFrame(handle: dom.ElementHandle): Promise<string | null> {
const remoteObject = toRemoteObject(handle);
if (!remoteObject.objectId)
return null;
const nodeInfo = await this._session.send('DOM.describeNode', {
objectId: remoteObject.objectId
});
if (!nodeInfo.ownerFrameId)
return null;
return this._page._frameManager.frame(nodeInfo.ownerFrameId);
return nodeInfo.ownerFrameId || null;
}

isElementHandle(remoteObject: any): boolean {
Expand Down
4 changes: 4 additions & 0 deletions src/webkit/wkPageProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ export class WKPageProxy {
return this._pagePromise;
}

existingPage(): Page | undefined {
return this._wkPage ? this._wkPage._page : undefined;
}

onPopupCreated(popupPageProxy: WKPageProxy) {
const wkPage = this._wkPage;
if (!wkPage || !wkPage._page.listenerCount(Events.Page.Popup))
Expand Down
2 changes: 1 addition & 1 deletion test/elementhandle.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
});
expect(await divHandle.ownerFrame()).toBe(page.mainFrame());
});
xit('should work for adopted elements', async({page,server}) => {
it.skip(FFOX)('should work for adopted elements', async({page,server}) => {
await page.goto(server.EMPTY_PAGE);
const [popup] = await Promise.all([
page.waitForEvent('popup'),
Expand Down

0 comments on commit 541fa95

Please sign in to comment.