From 96c558d54461e84b41052d144c74a4919dea0b1a Mon Sep 17 00:00:00 2001 From: Bogdan Ponomarenko Date: Thu, 12 Jul 2018 03:51:04 +0300 Subject: [PATCH] feat(elementhandle): introduce elementHandle.isIntersectingViewport() method. (#2673) This patch introduces `elementHandle.isIntersectingViewport()` method returns true if element is visible in the viewport. Fixes #2629. --- docs/api.md | 4 ++++ lib/ElementHandle.js | 18 ++++++++++++++ test/elementhandle.spec.js | 49 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/docs/api.md b/docs/api.md index c6ae9a447a0..46b1f96704a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -220,6 +220,7 @@ * [elementHandle.getProperties()](#elementhandlegetproperties) * [elementHandle.getProperty(propertyName)](#elementhandlegetpropertypropertyname) * [elementHandle.hover()](#elementhandlehover) + * [elementHandle.isIntersectingViewport()](#elementhandleisintersectingviewport) * [elementHandle.jsonValue()](#elementhandlejsonvalue) * [elementHandle.press(key[, options])](#elementhandlepresskey-options) * [elementHandle.screenshot([options])](#elementhandlescreenshotoptions) @@ -2548,6 +2549,9 @@ Fetches a single property from the objectHandle. This method scrolls element into view if needed, and then uses [page.mouse](#pagemouse) to hover over the center of the element. If the element is detached from DOM, the method throws an error. +#### elementHandle.isIntersectingViewport() +- returns: <[Promise]<[boolean]>> Resolves to true if the element is visible in the current viewport. + #### elementHandle.jsonValue() - returns: <[Promise]<[Object]>> diff --git a/lib/ElementHandle.js b/lib/ElementHandle.js index 07972fd1313..b601cb3dd1c 100644 --- a/lib/ElementHandle.js +++ b/lib/ElementHandle.js @@ -354,6 +354,24 @@ class ElementHandle extends JSHandle { } return result; } + + /** + * @returns {!Promise} + */ + isIntersectingViewport() { + return this.executionContext().evaluate( + node => new Promise(resolve => { + const callback = entries => { + resolve(entries[0].isIntersecting); + observer.disconnect(); + }; + const observer = new IntersectionObserver(callback); + + observer.observe(node); + }), + this + ); + } } function computeQuadArea(quad) { diff --git a/test/elementhandle.spec.js b/test/elementhandle.spec.js index 5ec5785affd..b46c4bc4748 100644 --- a/test/elementhandle.spec.js +++ b/test/elementhandle.spec.js @@ -198,6 +198,55 @@ module.exports.addTests = function({testRunner, expect}) { }); }); + describe('ElementHandle.isVisible', function() { + it('should return false if element is not visible in viewport', async({page, server}) => { + await page.setViewport({ width: 1000, height: 400 }); + await page.setContent(` + + + + + +
+
+
+
+ + + `); + + const box = await page.$('.red'); + const blue = await page.$('.blue'); + + expect(await box.isIntersectingViewport()).toBe(true); + expect(await blue.isIntersectingViewport()).toBe(false); + }); + }); + describe('ElementHandle.screenshot', function() { it('should work', async({page, server}) => { await page.setViewport({width: 500, height: 500});