siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
91 lines (74 loc) • 3.65 kB
JavaScript
/*
Siesta 5.6.1
Copyright(c) 2009-2022 Bryntum AB
https://bryntum.com/contact
https://bryntum.com/products/siesta/license
*/
/**
@class Siesta.Test.Browser.Role.CanGetElementFromPoint
*/
Role('Siesta.Test.Browser.Role.CanGetElementFromPoint', {
requires : [
'$'
],
does : [
Siesta.Util.Role.CanCalculatePageScroll
],
has : {
},
methods : {
/**
* This method will return the top-most DOM element at the specified coordinates from the test page. If
* the resulting element is an iframe and `shallow` argument is not passed as `true`
* it'll query the iframe for its element from the local point inside it.
*
* @param {Number} x The X coordinate, relative to the viewport area (currently visible part of the page)
* @param {Number} y The Y coordinate, relative to the viewport area (currently visible part of the page)
* @param {Boolean} [shallow] Pass `true` to _not_ check nested iframes if an element at the original coordinates is an iframe.
*
* @return {HTMLElement} The top-most element at the specified position on the test page
*/
elementFromPoint : function (viewportX, viewportY, shallow, fallbackEl, fullInfo) {
var queryRoot = this.global.document;
var el = queryRoot.elementFromPoint(viewportX, viewportY)
var localX = viewportX
var localY = viewportY
if (!shallow) {
// If we found IFRAME or shadow root and its not a `shallow` request, try to dig deeper
// Web component shadow root might return its own shadowRoot if empty
while (el && (el.nodeName.toUpperCase() === 'IFRAME' || (el.shadowRoot && el.shadowRoot !== queryRoot))) {
// if found iframe is loaded from different domain
// just accessing its "el.contentWindow.document" property will throw exception
try {
queryRoot = this.getQueryableContainerForNestedContext(el);
if (el.nodeName.toUpperCase() === 'IFRAME') {
var pageOffset = this.$(el).offset();
localX = viewportX - this.pageXtoViewportX(pageOffset.left)
localY = viewportY - this.pageYtoViewportY(pageOffset.top)
}
el = queryRoot.elementFromPoint(localX, localY);
// If nothing is found inside the shadowRoot, return outer web component element
if (!el && typeof queryRoot.constructor === 'ShadowRoot') {
fallbackEl = queryRoot.host;
}
}
catch (e) {
// digging deeper failed likely due to DOMException of x-domain iframe , restore the local coordinates
localX = viewportX
localY = viewportY
break;
}
}
}
// final fallback to the provided element or to the <body> element
el = el || fallbackEl || this.getBodyElement();
return fullInfo ? {
el : el,
// viewport coords in the inner frame
localXY : [localX, localY],
// viewport coords in the top frame (seems not needed, as just the input values are reused)
globalXY : [viewportX, viewportY]
} : el
}
}
});