UNPKG

@applitools/screenshoter

Version:

Applitools universal screenshoter for web and native applications

167 lines (145 loc) 5.3 kB
const utils = require('@applitools/utils') function makeScroller({logger, element, scrollingMode = 'mixed'}) { if (!element) return null const defaultElement = element return { element, moveTo, getInnerOffset, getContentSize, getClientRegion, getScrollOffset, getTranslateOffset, getShiftOffset, scrollTo, translateTo, shiftTo, preserveState, restoreState, hideScrollbars, restoreScrollbars, } async function moveTo(offset, element = defaultElement) { if (scrollingMode === 'scroll') return scrollTo(offset, element) if (scrollingMode === 'css') return translateTo(offset, element) if (scrollingMode === 'mixed') return shiftTo(offset, element) if (scrollingMode === 'mixed+') return shiftTo(offset, element, {formerlyCssScrollingMode: true}) } async function getInnerOffset(element = defaultElement) { if (scrollingMode === 'scroll') return getScrollOffset(element) if (scrollingMode === 'css') return getTranslateOffset(element) if (scrollingMode === 'mixed') return getShiftOffset(element) if (scrollingMode === 'mixed+') return getShiftOffset(element) } async function getContentSize(options) { const size = await element.getContentSize(options) return size } async function getClientRegion() { const region = await element.getClientRegion() // const location = await element.context.getLocationInPage() return region } async function getScrollOffset(element = defaultElement) { try { const offset = await element.getScrollOffset() return offset } catch (err) { // Sometimes it is expected e.g. on Appium, otherwise, take care logger.verbose(`Failed to extract current scroll offset!`, err) return {x: 0, y: 0} } } async function getTranslateOffset(element = defaultElement) { try { const offset = await element.getTranslateOffset() return offset } catch (err) { // Sometimes it is expected e.g. on Appium, otherwise, take care logger.verbose(`Failed to extract current translate offset!`, err) return {x: 0, y: 0} } } async function getShiftOffset(element = defaultElement) { try { const scrollOffset = await element.getScrollOffset() const translateOffset = await element.getTranslateOffset() return utils.geometry.offset(scrollOffset, translateOffset) } catch (err) { // Sometimes it is expected e.g. on Appium, otherwise, take care logger.verbose(`Failed to set current scroll offset!.`, err) return {x: 0, y: 0} } } async function scrollTo(offset, element = defaultElement) { try { const scrollOffset = await element.scrollTo(offset) return scrollOffset } catch (err) { // Sometimes it is expected e.g. on Appium, otherwise, take care logger.verbose(`Failed to set current scroll offset!.`, err) return {x: 0, y: 0} } } async function translateTo(offset, element = defaultElement) { try { await element.scrollTo({x: 0, y: 0}) const translateOffset = await element.translateTo(offset) return translateOffset } catch (err) { // Sometimes it is expected e.g. on Appium, otherwise, take care logger.verbose(`Failed to set current scroll offset!.`, err) return {x: 0, y: 0} } } async function shiftTo(offset, element = defaultElement, {formerlyCssScrollingMode} = {}) { try { const scrollOffset = await element.scrollTo(offset) if (utils.geometry.equals(scrollOffset, offset) && !formerlyCssScrollingMode) return scrollOffset // there is a "bug" in iOS that will not move a root element if it already scrolled, so it should be translated all the way const environment = await element.driver.getEnvironment() if (environment.isIOS && (await element.isRoot())) { const translateOffset = await element.translateTo(offset) return translateOffset } const remainingOffset = utils.geometry.offsetNegative(offset, scrollOffset) const translateOffset = await element.translateTo(remainingOffset) return utils.geometry.offset(scrollOffset, translateOffset) } catch (err) { // Sometimes it is expected e.g. on Appium, otherwise, take care logger.verbose(`Failed to set current scroll offset!.`, err) return {x: 0, y: 0} } } async function preserveState(element = defaultElement) { try { return element.preserveState() } catch (err) { logger.verbose(`Failed to get current transforms!.`, err) return {} } } async function restoreState(state, element = defaultElement) { try { await element.restoreState(state) } catch (err) { logger.verbose(`Failed to restore state!.`, err) } } async function hideScrollbars(element = defaultElement) { try { return element.hideScrollbars() } catch (err) { logger.verbose(`Failed to get current transforms!.`, err) return {} } } async function restoreScrollbars(state, element = defaultElement) { try { await element.restoreScrollbars(state) } catch (err) { logger.verbose(`Failed to restore state!.`, err) } } } module.exports = makeScroller