feat(elementhandle): introduce elementHandle.isIntersectingViewport() method. (#2673)

This patch introduces  `elementHandle.isIntersectingViewport()` method returns
true if element is visible in the viewport.

Fixes #2629.
This commit is contained in:
Bogdan Ponomarenko 2018-07-12 03:51:04 +03:00 committed by Andrey Lushnikov
parent 4f8d00e64e
commit 96c558d544
3 changed files with 71 additions and 0 deletions

View File

@ -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]>>

View File

@ -354,6 +354,24 @@ class ElementHandle extends JSHandle {
}
return result;
}
/**
* @returns {!Promise<boolean>}
*/
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) {

View File

@ -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(`
<html>
<head>
<style>
.scroll-container {
position: relative;
width: 600px;
background: green;
height: 150px;
overflow: hidden;
}
.red {
position: absolute;
top: 0;
left: 0;
height: 150px;
width: 150px;
background: red;
}
.blue {
position: absolute;
top: 0;
right: -160px;
height: 150px;
width: 150px;
background: blue;
}
</style>
</head>
<body>
<div class="scroll-container">
<div class="red"></div>
<div class="blue"></div>
</div>
</body>
</html>
`);
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});