fix(oopifs): translate coordinates to viewport (#3201)

Renderer-based method DOM.getContentQuads and DOM.getBoxModel return
coordinates relative to the local root's viewport, but we need them relative
to the root viewport.
This commit is contained in:
Dmitry Gozman 2020-07-28 15:52:33 -07:00 committed by GitHub
parent 6cb1e03713
commit fab5eba64f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 5 deletions

View File

@ -829,7 +829,21 @@ class FrameSession {
const y = Math.min(quad[1], quad[3], quad[5], quad[7]);
const width = Math.max(quad[0], quad[2], quad[4], quad[6]) - x;
const height = Math.max(quad[1], quad[3], quad[5], quad[7]) - y;
return {x, y, width, height};
const position = await this._framePosition();
if (!position)
return null;
return { x: x + position.x, y: y + position.y, width, height };
}
private async _framePosition(): Promise<types.Point | null> {
const frame = this._page._frameManager.frame(this._targetId);
if (!frame)
return null;
if (frame === this._page.mainFrame())
return { x: 0, y: 0 };
const element = await frame.frameElement();
const box = await element.boundingBox();
return box;
}
async _scrollRectIntoViewIfNeeded(handle: dom.ElementHandle, rect?: types.Rect): Promise<'error:notvisible' | 'error:notconnected' | 'done'> {
@ -851,11 +865,14 @@ class FrameSession {
});
if (!result)
return null;
const position = await this._framePosition();
if (!position)
return null;
return result.quads.map(quad => [
{ x: quad[0], y: quad[1] },
{ x: quad[2], y: quad[3] },
{ x: quad[4], y: quad[5] },
{ x: quad[6], y: quad[7] }
{ x: quad[0] + position.x, y: quad[1] + position.y },
{ x: quad[2] + position.x, y: quad[3] + position.y },
{ x: quad[4] + position.x, y: quad[5] + position.y },
{ x: quad[6] + position.x, y: quad[7] + position.y }
]);
}

View File

@ -293,6 +293,43 @@ describe.skip(!CHROMIUM)('OOPIF', function() {
]);
await browser.close();
});
it('ElementHandle.boundingBox() should work', async function({sppBrowser, sppPage, server}) {
const browser = sppBrowser;
const page = sppPage;
await page.goto(server.PREFIX + '/dynamic-oopif.html');
await page.$eval('iframe', iframe => {
iframe.style.width = '500px';
iframe.style.height = '500px';
iframe.style.marginLeft = '42px';
iframe.style.marginTop = '17px';
});
expect(await countOOPIFs(browser)).toBe(1);
const handle1 = await page.frames()[1].$('.box:nth-of-type(13)');
expect(await handle1.boundingBox()).toEqual({ x: 100 + 42, y: 50 + 17, width: 50, height: 50 });
await page.evaluate(() => goLocal());
expect(await countOOPIFs(browser)).toBe(0);
const handle2 = await page.frames()[1].$('.box:nth-of-type(13)');
expect(await handle2.boundingBox()).toEqual({ x: 100 + 42, y: 50 + 17, width: 50, height: 50 });
});
it('should click', async function({sppBrowser, sppPage, server}) {
const browser = sppBrowser;
const page = sppPage;
await page.goto(server.PREFIX + '/dynamic-oopif.html');
await page.$eval('iframe', iframe => {
iframe.style.width = '500px';
iframe.style.height = '500px';
iframe.style.marginLeft = '102px';
iframe.style.marginTop = '117px';
});
expect(await countOOPIFs(browser)).toBe(1);
const handle1 = await page.frames()[1].$('.box:nth-of-type(13)');
await handle1.evaluate(div => div.addEventListener('click', () => window._clicked = true, false));
await handle1.click();
expect(await handle1.evaluate(() => window._clicked)).toBe(true);
});
});
async function countOOPIFs(browser) {