diff --git a/lib/ElementHandle.js b/lib/ElementHandle.js index dfd4329d92c..4be4302e7d1 100644 --- a/lib/ElementHandle.js +++ b/lib/ElementHandle.js @@ -116,20 +116,22 @@ class ElementHandle extends JSHandle { } /** - * @return {!Promise} + * @return {!Promise<{x: number, y: number, width: number, height: number}>} */ async boundingBox() { - const boxModel = await this._client.send('DOM.getBoxModel', { + const {model} = await this._client.send('DOM.getBoxModel', { objectId: this._remoteObject.objectId }); - if (!boxModel || !boxModel.model) - return null; - return { - x: boxModel.model.margin[0], - y: boxModel.model.margin[1], - width: boxModel.model.width, - height: boxModel.model.height - }; + if (!model) + throw new Error('Node is detached from document'); + + const quad = model.border; + const x = Math.min(quad[0], quad[2], quad[4], quad[6]); + 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}; } /** diff --git a/test/golden/screenshot-element-padding-border.png b/test/golden/screenshot-element-padding-border.png new file mode 100644 index 00000000000..13f8880e95e Binary files /dev/null and b/test/golden/screenshot-element-padding-border.png differ diff --git a/test/golden/screenshot-element-rotate.png b/test/golden/screenshot-element-rotate.png new file mode 100644 index 00000000000..52e2a0f6d3c Binary files /dev/null and b/test/golden/screenshot-element-rotate.png differ diff --git a/test/test.js b/test/test.js index 46aa84432a6..79b6a730ee6 100644 --- a/test/test.js +++ b/test/test.js @@ -1503,6 +1503,33 @@ describe('Page', function() { const screenshot = await elementHandle.screenshot(); expect(screenshot).toBeGolden('screenshot-element-bounding-box.png'); })); + it('should take into account padding and border', SX(async function() { + await page.setViewport({width: 500, height: 500}); + await page.setContent('something above

 

'); + const elementHandle = await page.$('h1'); + const screenshot = await elementHandle.screenshot(); + expect(screenshot).toBeGolden('screenshot-element-padding-border.png'); + })); + it('should work with a rotated element', SX(async function() { + await page.setViewport({width: 500, height: 500}); + await page.setContent(`
 
`); + const elementHandle = await page.$('div'); + const screenshot = await elementHandle.screenshot(); + expect(screenshot).toBeGolden('screenshot-element-rotate.png'); + })); + it('should fail to screenshot a detached element', SX(async function() { + await page.setContent('

remove this

'); + const elementHandle = await page.$('h1'); + await page.evaluate(element => element.remove(), elementHandle); + const screenshotError = await elementHandle.screenshot().catch(error => error); + expect(screenshotError.message).toBe('Node is detached from document'); + })); }); describe('input', function() {