/*********************************************************************
 * Copyright (c) 2019 Red Hat, Inc.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 **********************************************************************/ import { IDriver } from '../driver/IDriver' ; import { inject , injectable } from 'inversify' ; import { TYPES } from '../inversify.types' ; import { error , ActionSequence } from 'selenium-webdriver' ; import 'reflect-metadata' ; import { ThenableWebDriver , By , until , WebElement } from 'selenium-webdriver' ; import { TestConstants } from '../TestConstants' ; import { Logger } from './Logger' ; import { TimeoutConstants } from '../TimeoutConstants' ; @ injectable ( ) export class DriverHelper { private readonly driver : ThenableWebDriver ; constructor ( @ inject ( TYPES . Driver ) driver ) { this . driver = driver . get ( ) ; } public getAction ( ) { Logger . trace ( 'DriverHelper.getAction' ) ; return this . driver . actions ( ) ; } deprecated see BrowserTabsUtil . maximize public async maximize ( ) { Logger . trace ( `DriverHelper.maximize` ) ; await this . driver . manage ( ) . window ( ) . maximize ( ) ; } public async isVisible ( locator ) { Logger . trace ( `DriverHelper.isVisible ${ locator }` ) ; try { const element = await this . driver . findElement ( locator ) ; const isVisible = await element . isDisplayed ( ) ; return isVisible ; } catch { return false ; } } public async wait ( milliseconds ) { Logger . trace ( `DriverHelper.wait (${ milliseconds } milliseconds)` ) ; await this . driver . sleep ( milliseconds ) ; } public async waitVisibilityBoolean ( locator , attempts = TestConstants . TS_SELENIUM_DEFAULT_ATTEMPTS , polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ) { Logger . trace ( `DriverHelper.waitVisibilityBoolean ${ locator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { const isVisible = await this . isVisible ( locator ) ; if ( isVisible ) { return true ; } await this . wait ( polling ) ; } return false ; } public async waitDisappearanceBoolean ( locator , attempts = TestConstants . TS_SELENIUM_DEFAULT_ATTEMPTS , polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ) { Logger . trace ( `DriverHelper.waitDisappearanceBoolean ${ locator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { const isVisible = await this . isVisible ( locator ) ; if ( ! isVisible ) { return true ; } await this . wait ( polling ) ; } return false ; } public async waitVisibility ( elementLocator , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.waitVisibility ${ elementLocator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . driver . wait ( until . elementLocated ( elementLocator ) , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.waitVisibility - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { if ( attempts !== 1 ) { Logger . trace ( `DriverHelper.waitVisibility - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; } continue ; } if ( err instanceof error . NoSuchWindowError ) { Logger . trace ( `DriverHelper.waitVisibility - failed with NoSuchWindow exception. Attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.waitVisibility - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { const visibleWebElement = await this . driver . wait ( until . elementIsVisible ( element ) , polling ) ; Logger . trace ( 'DriverHelper.waitVisibility - Element is located and is visible.' ) ; return visibleWebElement ; } catch ( err ) { if ( err instanceof error . TimeoutError ) { if ( attempts !== 1 ) { Logger . trace ( `DriverHelper.waitVisibility - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; } continue ; } if ( err instanceof error . StaleElementReferenceError ) { Logger . debug ( `DriverHelper.waitVisibility - Stale element error - ${ err }` ) ; await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.waitVisibility - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum visibility checkings attempts for '${ elementLocator }' element, timeouted after ${ timeout }` ) ; } public async waitPresence ( elementLocator , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.waitPresence ${ elementLocator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { try { const webElement = await this . driver . wait ( until . elementLocated ( elementLocator ) , polling ) ; return webElement ; } catch ( err ) { if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.waitPresence - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.waitPresence - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum presence checkings attempts, problems with 'StaleElementReferenceError' of '${ elementLocator }' element` ) ; } public async waitAllPresence ( elementLocator , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.waitAllPresence ${ elementLocator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { try { const webElements = await this . driver . wait ( until . elementsLocated ( elementLocator ) , polling ) ; return webElements ; } catch ( err ) { if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.waitAllPresence - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.waitAllPresence - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum presence checkings attempts, problems with 'StaleElementReferenceError' of '${ elementLocator }' element` ) ; } public async waitAllVisibility ( locators , timeout ) { Logger . trace ( `DriverHelper.waitAllVisibility ${ locators }` ) ; for ( const elementLocator of locators ) { await this . waitVisibility ( elementLocator , timeout ) ; } } public async waitDisappearance ( elementLocator , attempts = TestConstants . TS_SELENIUM_DEFAULT_ATTEMPTS , polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ) { Logger . trace ( `DriverHelper.waitDisappearance ${ elementLocator }` ) ; const isDisappeared = await this . waitDisappearanceBoolean ( elementLocator , attempts , polling ) ; if ( ! isDisappeared ) { throw new error . TimeoutError ( `Waiting attempts exceeded, element '${ elementLocator }' is still visible` ) ; } } public async waitDisappearanceWithTimeout ( elementLocator , timeout ) { Logger . trace ( `DriverHelper.waitDisappearanceWithTimeout ${ elementLocator }` ) ; await this . getDriver ( ) . wait ( async ( ) => { const isVisible = await this . isVisible ( elementLocator ) ; if ( ! isVisible ) { return true ; } } , timeout ) ; } public async waitAllDisappearance ( locators , attemptsPerLocator = TestConstants . TS_SELENIUM_DEFAULT_ATTEMPTS , pollingPerLocator = TestConstants . TS_SELENIUM_DEFAULT_POLLING ) { Logger . trace ( `DriverHelper.waitAllDisappearance ${ locators }` ) ; for ( const elementLocator of locators ) { await this . waitDisappearance ( elementLocator , attemptsPerLocator , pollingPerLocator ) ; } } public async waitAndClick ( elementLocator , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.waitAndClick ${ elementLocator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . waitVisibility ( elementLocator , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.waitAndClick - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.waitAndClick - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.waitAndClick - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { await element . click ( ) ; return ; } catch ( err ) { if ( err instanceof error . StaleElementReferenceError ) { Logger . debug ( `DriverHelper.waitAndClik - ${ elementLocator } - StaleElementReferenceError - ${ err }` ) ; await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.waitAndClick - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum clicking attempts, the '${ elementLocator }' element is not clickable` ) ; } public async waitAndGetElementAttribute ( elementLocator , attribute , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.waitAndGetElementAttribute ${ elementLocator } attribute: '${ attribute }'` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . waitVisibility ( elementLocator , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.waitAndGetElementAttribute - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.waitAndGetElementAttribute - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.waitAndGetElementAttribute - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { const attributeValue = await element . getAttribute ( attribute ) ; return attributeValue ; } catch ( err ) { if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.waitAndGetElementAttribute - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum gettin of the '${ attribute }' attribute attempts, from the '${ elementLocator }' element` ) ; } public async waitAndGetCssValue ( elementLocator , cssAttribute , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.waitAndGetCssValue ${ elementLocator } cssAttribute: ${ cssAttribute }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . waitVisibility ( elementLocator , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.waitAndGetCssValue - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.waitAndGetCssValue - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.waitAndGetCssValue - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { const cssAttributeValue = await element . getCssValue ( cssAttribute ) ; return cssAttributeValue ; } catch ( err ) { if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.waitAndGetCssValue - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum gettin of the '${ cssAttribute }' css attribute attempts, from the '${ elementLocator }' element` ) ; } public async waitAttributeValue ( elementLocator , attribute , expectedValue , timeout ) { Logger . trace ( `DriverHelper.waitAttributeValue ${ elementLocator }` ) ; await this . driver . wait ( async ( ) => { const attributeValue = await this . waitAndGetElementAttribute ( elementLocator , attribute , timeout ) ; return expectedValue === attributeValue ; } , timeout , `The '${ attribute }' attribute value doesn't match with expected value '${ expectedValue }'` ) ; } public async type ( elementLocator , text , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.type ${ elementLocator } text: ${ text }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . waitVisibility ( elementLocator , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.type - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.type - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.type - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { await element . sendKeys ( text ) ; return ; } catch ( err ) { if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.type - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum typing attempts, to the '${ elementLocator }' element` ) ; } public async typeToInvisible ( elementLocator , text , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.typeToInvisible ${ elementLocator } text: ${ text }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . waitPresence ( elementLocator , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.typeToInvisible - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.typeToInvisible - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.typeToInvisible - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { await element . sendKeys ( text ) ; return ; } catch ( err ) { if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.typeToInvisible - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum typing attempts, to the '${ elementLocator }' element` ) ; } public async clear ( elementLocator , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.clear ${ elementLocator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . waitVisibility ( elementLocator , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.clear - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.clear - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.clear - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { await element . clear ( ) ; return ; } catch ( err ) { if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.clear - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum clearing attempts, to the '${ elementLocator }' element` ) ; } public async clearInvisible ( elementLocator , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.clearInvisible ${ elementLocator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . waitPresence ( elementLocator , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.clearInvisible - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.clearInvisible - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.clearInvisible - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { await element . clear ( ) ; return ; } catch ( err ) { if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.clearInvisible - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum clearing attempts, to the '${ elementLocator }' element` ) ; } public async enterValue ( elementLocator , text , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { Logger . trace ( `DriverHelper.enterValue ${ elementLocator } text: ${ text }` ) ; await this . waitVisibility ( elementLocator , timeout ) ; await this . clear ( elementLocator ) ; await this . waitAttributeValue ( elementLocator , 'value' , '' , timeout ) ; await this . type ( elementLocator , text , timeout ) ; await this . waitAttributeValue ( elementLocator , 'value' , text , timeout ) ; } public async waitAndSwitchToFrame ( iframeLocator , timeout ) { Logger . trace ( `DriverHelper.waitAndSwitchToFrame ${ iframeLocator }` ) ; await this . driver . wait ( until . ableToSwitchToFrame ( iframeLocator ) , timeout ) ; } public async waitAndGetText ( elementLocator , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.waitAndGetText ${ elementLocator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . waitVisibility ( elementLocator , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.waitAndGetText - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.waitAndGetText - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.waitAndGetText - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { const innerText = await element . getText ( ) ; return innerText ; } catch ( err ) { if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.waitAndGetText - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum text obtaining attempts, from the '${ elementLocator }' element` ) ; } public async waitAndGetValue ( elementLocator , timeout ) { Logger . trace ( `DriverHelper.waitAndGetValue ${ elementLocator }` ) ; const elementValue = await this . waitAndGetElementAttribute ( elementLocator , 'value' , timeout ) ; return elementValue ; } public async waitUntilTrue ( callback , timeout ) { Logger . trace ( 'DriverHelper.waitUntilTrue' ) ; await this . driver . wait ( callback , timeout ) ; } deprecated see BrowserTabsUtil . refreshPage public async reloadPage ( ) { Logger . debug ( 'DriverHelper.reloadPage' ) ; await this . driver . navigate ( ) . refresh ( ) ; } deprecated see BrowserTabsUtil . navigateAndWaitToUrl public async navigateAndWaitToUrl ( url , timeout = TimeoutConstants . TS_SELENIUM_WAIT_FOR_URL ) { Logger . trace ( `DriverHelper.navigateAndWaitToUrl ${ url }` ) ; await this . navigateToUrl ( url ) ; await this . waitURL ( url , timeout ) ; } deprecated see BrowserTabsUtil . navigateTo public async navigateToUrl ( url ) { Logger . debug ( `DriverHelper.navigateToUrl ${ url }` ) ; await this . driver . navigate ( ) . to ( url ) ; } deprecated see BrowserTabsUtil . waitURL public async waitURL ( expectedUrl , timeout ) { Logger . trace ( `DriverHelper.waitURL ${ expectedUrl }` ) ; await this . getDriver ( ) . wait ( async ( ) => { const currentUrl = await this . getDriver ( ) . getCurrentUrl ( ) ; const urlEquals = currentUrl === expectedUrl ; if ( urlEquals ) { return true ; } } , timeout ) ; } public async scrollTo ( elementLocator , timeout = TimeoutConstants . TS_SELENIUM_CLICK_ON_VISIBLE_ITEM ) { const polling = TestConstants . TS_SELENIUM_DEFAULT_POLLING ; const attempts = Math . ceil ( timeout / polling ) ; Logger . trace ( `DriverHelper.scrollTo ${ elementLocator }` ) ; for ( let i = 0 ; i < attempts ; i ++ ) { let element ; try { element = await this . waitPresence ( elementLocator , polling ) ; } catch ( err ) { if ( i >= attempts - 1 ) { Logger . error ( `DriverHelper.scrollTo - failed with exception, out of attempts - ${ err }` ) ; throw err ; } if ( err instanceof error . TimeoutError ) { Logger . trace ( `DriverHelper.scrollTo - Polling timed out attempt #${ ( i + 1 ) }, retrying with ${ polling }ms timeout` ) ; continue ; } Logger . error ( `DriverHelper.scrollTo - failed with an unexpected exception - ${ err }` ) ; throw err ; } try { await this . getAction ( ) . mouseMove ( element ) . perform ( ) ; return ; } catch ( err ) { if ( err instanceof error . StaleElementReferenceError ) { await this . wait ( polling ) ; continue ; } Logger . error ( `DriverHelper.scrollTo - failed with an unexpected exception - ${ err }` ) ; throw err ; } } throw new error . TimeoutError ( `Exceeded maximum mouse move attempts, for the '${ elementLocator }' element` ) ; } deprecated see BrowserTabsUtil . getCurrentUrl public async getCurrentUrl ( ) { return await this . driver . getCurrentUrl ( ) ; } getDriver ( ) { Logger . trace ( 'DriverHelper.getDriver' ) ; return this . driver ; } public sleep ( time ) { this . driver . sleep ( time ) ; } }