#include-once ; standard UDF's #include ; Needed For _WD_UpdateDriver #include #include ; Needed For _WD_UpdateDriver >> _VersionCompare #include ; Needed For _WD_UpdateDriver >> _WinAPI_GetBinaryType and _WD_DownloadFile >> _WinAPI_FileInUse ; WebDriver related UDF's #include "wd_core.au3" #Region Copyright #cs * WD_Helper.au3 * * MIT License * * Copyright (c) 2023 Dan Pollak (@Danp2) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. #ce #EndRegion Copyright #Region Many thanks to: #cs - Jonathan Bennett (@Jon) and the AutoIt Team - Thorsten Willert (@Stilgar), author of FF.au3, which I've used as a model - MichaƂ Lipok (@mLipok) for all his contribution #ce #EndRegion Many thanks to: #ignorefunc _HtmlTableGetWriteToArray #Region Global Constants Global Enum _ $_WD_OPTION_None = 0, _ $_WD_OPTION_Visible = 1, _ $_WD_OPTION_Enabled = 2, _ $_WD_OPTION_Element = 4, _ $_WD_OPTION_NoMatch = 8, _ $_WD_OPTION_Hidden = 16 Global Enum _ $_WD_OPTION_Standard, _ $_WD_OPTION_Advanced Global Enum _ $_WD_STATUS_Invalid, _ $_WD_STATUS_Valid, _ $_WD_STATUS_Reconnect Global Enum _ $_WD_TARGET_FirstTab, _ $_WD_TARGET_LastTab Global Enum _ $_WD_BUTTON_Left = 0, _ $_WD_BUTTON_Middle = 1, _ $_WD_BUTTON_Right = 2 Global Enum _ $_WD_STORAGE_Local = 0, _ $_WD_STORAGE_Session = 1 Global Enum _ ; _WD_FrameList() , _WD_FrameListFindElement() $_WD_FRAMELIST_Absolute = 0, _ $_WD_FRAMELIST_Relative = 1, _ $_WD_FRAMELIST_Attributes = 2, _ $_WD_FRAMELIST_URL = 3, _ $_WD_FRAMELIST_BodyID = 4, _ $_WD_FRAMELIST_FrameVisibility = 5, _ $_WD_FRAMELIST_MatchedElements = 6, _ ; array of matched element from _WD_FrameListFindElement() $_WD_FRAMELIST__COUNTER Global Enum _ ; https://www.w3schools.com/jsref/prop_doc_readystate.asp $_WD_READYSTATE_Uninitialized, _ ; Has not started loading $_WD_READYSTATE_Loading, _ ; Is loading $_WD_READYSTATE_Loaded, _ ; Has been loaded $_WD_READYSTATE_Interactive, _ ; Has loaded enough to interact with $_WD_READYSTATE_Complete, _ ; Fully loaded $_WD_READYSTATE__COUNTER Global Const $aWD_READYSTATE[$_WD_READYSTATE__COUNTER][2] = [ _ ["uninitialized", "Has not started loading"], _ ["loading", "Is loading"], _ ["loaded", "Has been loaded"], _ ["interactive", "Has loaded enough to interact with"], _ ["complete", "Fully loaded"] _ ] Global Enum _ ; Column positions of $aWD_READYSTATE $_WD_READYSTATE_State, _ $_WD_READYSTATE_Desc #EndRegion Global Constants ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WD_NewTab ; Description ...: Create new tab in current browser session. ; Syntax ........: _WD_NewTab($sSession[, $bSwitch = Default[, $iTimeout = Default[, $sURL = Default[, $sFeatures = Default]]]]) ; Parameters ....: $sSession - Session ID from _WD_CreateSession ; $bSwitch - [optional] Switch session context to new tab? Default is True ; $iTimeout - [optional] Period of time (in milliseconds) to wait before exiting function ; $sURL - [optional] URL to be loaded in new tab ; $sFeatures - [optional] Comma-separated list of requested features of the new tab ; Return values .: Success - String representing handle of new tab. ; Failure - "" (empty string) and sets @error to one of the following values: ; - $_WD_ERROR_Exception ; - $_WD_ERROR_Timeout ; Author ........: Danp2 ; Modified ......: mLipok ; Remarks .......: Specifying any features other than noopener or noreferrer, also has the effect of requesting a popup. ; See the link below for further details and a list of available features. ; Related .......: _WD_Window, _WD_LastHTTPResult ; Link ..........: https://developer.mozilla.org/en-US/docs/Web/API/Window/open#window_features ; Example .......: No ; =============================================================================================================================== Func _WD_NewTab($sSession, $bSwitch = Default, $iTimeout = Default, $sURL = Default, $sFeatures = Default) Local Const $sFuncName = "_WD_NewTab" Local Const $sParameters = 'Parameters: Switch=' & $bSwitch & ' Timeout=' & $iTimeout & ' URL=' & $sURL & ' Features=' & $sFeatures Local $sTabHandle = '', $sLastTabHandle, $hWaitTimer, $iTabIndex, $aTemp If $bSwitch = Default Then $bSwitch = True If $iTimeout = Default Then $iTimeout = $_WD_DefaultTimeout If $sURL = Default Then $sURL = '' If $sFeatures = Default Then $sFeatures = '' ; Get handle for current tab Local $sCurrentTabHandle = _WD_Window($sSession, 'window') If $sFeatures = '' Then $sTabHandle = _WD_Window($sSession, 'new', '{"type":"tab"}') If @error = $_WD_ERROR_Success Then _WD_Window($sSession, 'Switch', '{"handle":"' & $sTabHandle & '"}') If $sURL Then _WD_Navigate($sSession, $sURL) If Not $bSwitch Then _WD_Window($sSession, 'Switch', '{"handle":"' & $sCurrentTabHandle & '"}') Else Return SetError(__WD_Error($sFuncName, $_WD_ERROR_Exception, $sParameters), 0, $sTabHandle) EndIf Else Local $aHandles = _WD_Window($sSession, 'handles') If @error <> $_WD_ERROR_Success Or Not IsArray($aHandles) Then Return SetError(__WD_Error($sFuncName, $_WD_ERROR_Exception, $sParameters), 0, $sTabHandle) EndIf Local $iTabCount = UBound($aHandles) ; Get handle to current last tab $sLastTabHandle = $aHandles[$iTabCount - 1] If $sCurrentTabHandle Then ; Search for current tab handle in array of tab handles. If not found, ; then make the current tab handle equal to the last tab $iTabIndex = _ArraySearch($aHandles, $sCurrentTabHandle) If @error Then $sCurrentTabHandle = $sLastTabHandle $iTabIndex = $iTabCount - 1 EndIf Else _WD_Window($sSession, 'Switch', '{"handle":"' & $sLastTabHandle & '"}') $sCurrentTabHandle = $sLastTabHandle $iTabIndex = $iTabCount - 1 EndIf _WD_ExecuteScript($sSession, "window.open(arguments[0], '', arguments[1])", '"' & $sURL & '","' & $sFeatures & '"') If @error <> $_WD_ERROR_Success Then Return SetError(__WD_Error($sFuncName, $_WD_ERROR_Exception, $sParameters), 0, $sTabHandle) EndIf $hWaitTimer = TimerInit() While 1 $aTemp = _WD_Window($sSession, 'handles') If UBound($aTemp) > $iTabCount Then $sTabHandle = $aTemp[$iTabIndex + 1] ExitLoop EndIf If TimerDiff($hWaitTimer) > $iTimeout Then Return SetError(__WD_Error($sFuncName, $_WD_ERROR_Timeout, $sParameters), 0, $sTabHandle) __WD_Sleep(10) If @error Then Return SetError(__WD_Error($sFuncName, @error, $sParameters), 0, $sTabHandle) WEnd If $bSwitch Then _WD_Window($sSession, 'Switch', '{"handle":"' & $sTabHandle & '"}') Else _WD_Window($sSession, 'Switch', '{"handle":"' & $sCurrentTabHandle & '"}') EndIf EndIf Return SetError(__WD_Error($sFuncName, $_WD_ERROR_Success, $sParameters), 0, $sTabHandle) EndFunc ;==>_WD_NewTab ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WD_Attach ; Description ...: Attach to existing browser tab. ; Syntax ........: _WD_Attach($sSession, $sSearch[, $sMode = Default]) ; Parameters ....: $sSession - Session ID from _WD_CreateSession ; $sSearch - String to search for ; $sMode - [optional] One of the following search modes: ; |Title (default) ; |URL ; |HTML ; Return values .: Success - String representing handle of matching tab. ; Failure - "" (empty string) and sets @error to one of the following values: ; - $_WD_ERROR_InvalidDataType ; - $_WD_ERROR_NoMatch ; - $_WD_ERROR_GeneralError ; Author ........: Danp2 ; Modified ......: ; Remarks .......: ; Related .......: _WD_Window, _WD_LastHTTPResult ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _WD_Attach($sSession, $sSearch, $sMode = Default) Local Const $sFuncName = "_WD_Attach" Local Const $sParameters = 'Parameters: Search=' & $sSearch & ' Mode=' & $sMode Local $sTabHandle = '', $bFound = False, $sCurrentTab = '', $aHandles Local $iErr = $_WD_ERROR_Success If $sMode = Default Then $sMode = 'title' $aHandles = _WD_Window($sSession, 'handles') $iErr = @error If $iErr = $_WD_ERROR_Success Then $sCurrentTab = _WD_Window($sSession, 'window') For $sHandle In $aHandles _WD_Window($sSession, 'Switch', '{"handle":"' & $sHandle & '"}') Switch $sMode Case "title", "url" If StringInStr(_WD_Action($sSession, $sMode), $sSearch) > 0 Then $bFound = True $sTabHandle = $sHandle ExitLoop EndIf Case 'html' If StringInStr(_WD_GetSource($sSession), $sSearch) > 0 Then $bFound = True $sTabHandle = $sHandle ExitLoop EndIf Case Else Return SetError(__WD_Error($sFuncName, $_WD_ERROR_InvalidDataType, "(Title|URL|HTML) $sMode=>" & $sMode), 0, $sTabHandle) EndSwitch Next If Not $bFound Then ; Restore prior active tab If $sCurrentTab <> '' Then _WD_Window($sSession, 'Switch', '{"handle":"' & $sCurrentTab & '"}') EndIf $iErr = $_WD_ERROR_NoMatch EndIf ElseIf Not $_WD_DetailedErrors Then $iErr = $_WD_ERROR_GeneralError EndIf Return SetError(__WD_Error($sFuncName, $iErr, $sParameters), 0, $sTabHandle) EndFunc ;==>_WD_Attach ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WD_LinkClickByText ; Description ...: Simulate a mouse click on a link with text matching the provided string. ; Syntax ........: _WD_LinkClickByText($sSession, $sText[, $bPartial = Default[, $sStartNodeID = Default]]) ; Parameters ....: $sSession - Session ID from _WD_CreateSession ; $sText - Text to find in link ; $bPartial - [optional] Search by partial text? Default is True ; $sStartNodeID - [optional] Element ID to use as starting HTML node. Default is "" ; Return values .: Success - None. ; Failure - "" (empty string) and sets @error to one of the following values: ; - $_WD_ERROR_Exception ; - $_WD_ERROR_NoMatch ; Author ........: Danp2 ; Modified ......: ; Remarks .......: ; Related .......: _WD_FindElement, _WD_ElementAction, _WD_LastHTTPResult ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _WD_LinkClickByText($sSession, $sText, $bPartial = Default, $sStartNodeID = Default) Local Const $sFuncName = "_WD_LinkClickByText" Local Const $sParameters = 'Parameters: Text=' & $sText & ' Partial=' & $bPartial & ' StartElement=' & $sStartNodeID If $bPartial = Default Then $bPartial = True If $sStartNodeID = Default Then $sStartNodeID = "" Local $sElement = _WD_FindElement($sSession, ($bPartial) ? $_WD_LOCATOR_ByPartialLinkText : $_WD_LOCATOR_ByLinkText, $sText, $sStartNodeID) Local $iErr = @error If $iErr = $_WD_ERROR_Success Then _WD_ElementAction($sSession, $sElement, 'click') $iErr = @error If $iErr <> $_WD_ERROR_Success And Not $_WD_DetailedErrors Then $iErr = $_WD_ERROR_Exception EndIf Else $iErr = $_WD_ERROR_NoMatch EndIf Return SetError(__WD_Error($sFuncName, $iErr, $sParameters), 0, "") EndFunc ;==>_WD_LinkClickByText ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WD_WaitElement ; Description ...: Wait for an element in the current tab before returning. ; Syntax ........: _WD_WaitElement($sSession, $sStrategy, $sSelector[, $iDelay = Default[, $iTimeout = Default[, $iOptions = Default]]]) ; Parameters ....: $sSession - Session ID from _WD_CreateSession ; $sStrategy - Locator strategy. See defined constant $_WD_LOCATOR_* for allowed values ; $sSelector - Indicates how the WebDriver should traverse through the HTML DOM to locate the desired element(s). ; $iDelay - [optional] Milliseconds to wait before initially checking status ; $iTimeout - [optional] Period of time (in milliseconds) to wait before exiting function ; $iOptions - [optional] Binary flags to perform additional actions: ; |$_WD_OPTION_None (0) = No optional feature processing ; |$_WD_OPTION_Visible (1) = Confirm element is visible ; |$_WD_OPTION_Enabled (2) = Confirm element is enabled ; |$_WD_OPTION_NoMatch (8) = Confirm element is not found ; |$_WD_OPTION_Hidden (16) = Confirm element is not visible ; Return values .: Success - Element ID returned by web driver. ; Failure - "" (empty string) and sets @error to one of the following values: ; - $_WD_ERROR_Exception ; - $_WD_ERROR_InvalidArgue ; - $_WD_ERROR_Timeout ; - $_WD_ERROR_UserAbort ; Author ........: Danp2 ; Modified ......: mLipok ; Remarks .......: ; Related .......: _WD_FindElement, _WD_ElementAction, _WD_LastHTTPResult ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _WD_WaitElement($sSession, $sStrategy, $sSelector, $iDelay = Default, $iTimeout = Default, $iOptions = Default) Local Const $sFuncName = "_WD_WaitElement" Local Const $sParameters = 'Parameters: Strategy=' & $sStrategy & ' Selector=' & $sSelector & ' Delay=' & $iDelay & ' Timeout=' & $iTimeout & ' Options=' & $iOptions Local $iErr, $sElement, $bIsVisible = True, $bIsEnabled = True $_WD_HTTPRESULT = 0 $_WD_HTTPRESPONSE = '' If $iDelay = Default Then $iDelay = 0 If $iTimeout = Default Then $iTimeout = $_WD_DefaultTimeout If $iOptions = Default Then $iOptions = $_WD_OPTION_None Local Const $bVisible = BitAND($iOptions, $_WD_OPTION_Visible) Local Const $bEnabled = BitAND($iOptions, $_WD_OPTION_Enabled) Local Const $bNoMatch = BitAND($iOptions, $_WD_OPTION_NoMatch) Local Const $bHidden = BitAND($iOptions, $_WD_OPTION_Hidden) ; Other options aren't valid if No Match or Hidden option is supplied If ($bNoMatch And $iOptions <> $_WD_OPTION_NoMatch) Or _ ($bHidden And $iOptions <> $_WD_OPTION_Hidden) Then $iErr = $_WD_ERROR_InvalidArgue Else __WD_Sleep($iDelay) $iErr = @error ; prevent multiple errors https://github.com/Danp2/au3WebDriver/pull/290#issuecomment-1100707095 Local $_WD_DEBUG_Saved = $_WD_DEBUG ; save current DEBUG level ; Prevent logging from _WD_FindElement if not in Full debug mode If $_WD_DEBUG <> $_WD_DEBUG_Full Then $_WD_DEBUG = $_WD_DEBUG_None Local $hWaitTimer = TimerInit() While 1 If $iErr Then ExitLoop $sElement = _WD_FindElement($sSession, $sStrategy, $sSelector) $iErr = @error If $iErr <> $_WD_ERROR_Success And $iErr <> $_WD_ERROR_NoMatch Then ; Exit loop if unexpected error occurs ExitLoop ElseIf $iErr = $_WD_ERROR_NoMatch And $bNoMatch Then ; if element wasn't found and "no match" option is active ; exit loop indicating success $iErr = $_WD_ERROR_Success ExitLoop ElseIf $iErr = $_WD_ERROR_Success And Not $bNoMatch Then ; if element was found and "no match" option isn't active ; check other options If $bVisible Or $bHidden Then $bIsVisible = _WD_ElementAction($sSession, $sElement, 'displayed') If @error Then $bIsVisible = False EndIf EndIf If $bEnabled Then $bIsEnabled = _WD_ElementAction($sSession, $sElement, 'enabled') If @error Then $bIsEnabled = False EndIf EndIf Select Case $bHidden If Not $bIsVisible Then ExitLoop Case $bIsVisible And $bIsEnabled ExitLoop Case Else $sElement = '' EndSelect EndIf If (TimerDiff($hWaitTimer) > $iTimeout) Then $iErr = $_WD_ERROR_Timeout ExitLoop EndIf __WD_Sleep(10) $iErr = @error WEnd $_WD_DEBUG = $_WD_DEBUG_Saved ; restore DEBUG level EndIf Return SetError(__WD_Error($sFuncName, $iErr, $sParameters), 0, $sElement) EndFunc ;==>_WD_WaitElement ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WD_WaitScript ; Description ...: Wait for a JavaScript snippet to return true. ; Syntax ........: _WD_WaitScript($sSession, $sJavaScript[, $iDelay = Default[, $iTimeout = Default[, $iOptions = Default]]]) ; Parameters ....: $sSession - Session ID from _WD_CreateSession ; $sJavaScript - JavaScript to run ; $iDelay - [optional] Milliseconds to wait before initially checking status ; $iTimeout - [optional] Period of time (in milliseconds) to wait before exiting function ; Return values .: Success - True ; Failure - False and sets @error to one of the following values: ; - $_WD_ERROR_InvalidArgue ; - $_WD_ERROR_RetValue ; - $_WD_ERROR_Exception ; - $_WD_ERROR_Timeout ; - $_WD_ERROR_UserAbort ; Author ........: yehiaserag ; Modified ......: ; Remarks .......: The Javascript needs to return either True or False. ; Related .......: _WD_ExecuteScript ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _WD_WaitScript($sSession, $sJavaScript, $iDelay = Default, $iTimeout = Default) Local Const $sFuncName = "_WD_WaitScript" Local Const $sParameters = 'Parameters: JavaScript=' & $sJavaScript & ' Delay=' & $iDelay & ' Timeout=' & $iTimeout Local $iErr Local $bValue = False If $iDelay = Default Then $iDelay = 0 If $iTimeout = Default Then $iTimeout = $_WD_DefaultTimeout If StringLeft($sJavaScript, 6) <> "return" Then $iErr = $_WD_ERROR_InvalidArgue Else __WD_Sleep($iDelay) $iErr = @error ; prevent multiple errors https://github.com/Danp2/au3WebDriver/pull/290#issuecomment-1100707095 Local $_WD_DEBUG_Saved = $_WD_DEBUG ; save current DEBUG level ; Prevent logging from _WD_ExecuteScript if not in Full debug mode If $_WD_DEBUG <> $_WD_DEBUG_Full Then $_WD_DEBUG = $_WD_DEBUG_None Local $hWaitTimer = TimerInit() While 1 If $iErr Then ExitLoop $bValue = _WD_ExecuteScript($sSession, 'return !!((function(){' & $sJavaScript & '})())', Default, Default, $_WD_JSON_Value) $iErr = @error If $iErr <> $_WD_ERROR_Success Then ; Exit loop if unexpected error occurs ExitLoop ElseIf $bValue = False Then If (TimerDiff($hWaitTimer) > $iTimeout) Then $iErr = $_WD_ERROR_Timeout ExitLoop EndIf __WD_Sleep(10) $iErr = @error Else $iErr = $_WD_ERROR_Success ExitLoop EndIf WEnd $_WD_DEBUG = $_WD_DEBUG_Saved ; restore DEBUG level EndIf Return SetError(__WD_Error($sFuncName, $iErr, $sParameters), 0, $bValue) EndFunc ;==>_WD_WaitScript ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WD_DebugSwitch ; Description ...: Switch to new debug level or switch back to saved debug level ; Syntax ........: _WD_DebugSwitch([$vMode = Default]) ; Parameters ....: $vMode - [optional] Set new $_WD_DEBUG level. When not specified (Default) restore saved debug level. ; Return values .: Success - current stack size ; Failure - negative values indicate an error ; Author ........: mLipok ; Modified ......: ; Remarks .......: @error and @extended values are preserved by this function and did not originate within it ; Related .......: ; Link ..........: ; Example .......: _WD_DebugSwitch($_WD_DEBUG_Full) ; =============================================================================================================================== Func _WD_DebugSwitch($vMode = Default, $iErr = @error, $iExt = @extended) Local Const $sFuncName = "_WD_DebugSwitch" Local Static $a_WD_DEBUG_SavedStack[0] ; first usage - empty stack array Local $iStackSize = UBound($a_WD_DEBUG_SavedStack) Local $sMessage = '' If $vMode = Default Then ; restoring saved debug level If $iStackSize Then $_WD_DEBUG = $a_WD_DEBUG_SavedStack[$iStackSize - 1] ; restore previous debug level from last element on the stack $iStackSize -= 1 ; decrease stack size ReDim $a_WD_DEBUG_SavedStack[$iStackSize] ; trim array - stack last element Else $iStackSize = -1 $sMessage = 'There are no saved debug levels' EndIf ElseIf IsInt($vMode) And $vMode >= $_WD_DEBUG_None And $vMode <= $_WD_DEBUG_Full Then ; setting new debug level $iStackSize += 1 ; increase stack size ReDim $a_WD_DEBUG_SavedStack[$iStackSize] ; resize array - add new position to the stack $a_WD_DEBUG_SavedStack[$iStackSize - 1] = $_WD_DEBUG ; store current debug level to the stack $_WD_DEBUG = $vMode ; set new debug level Else $iStackSize = -2 $sMessage = 'Invalid argument in function-call' EndIf $sMessage &= " / " & (($iStackSize < 0) ? (" error code: ") : (" stack size: ")) & $iStackSize __WD_ConsoleWrite($sFuncName & ": " & $sMessage, $_WD_DEBUG_Info) Return SetError($iErr, $iExt, $iStackSize) ; do not use __WD_Error() here as $iErr and $iExt are preserved and not belongs to this function EndFunc ;==>_WD_DebugSwitch ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WD_GetMouseElement ; Description ...: Retrieves reference to element below mouse pointer. ; Syntax ........: _WD_GetMouseElement($sSession) ; Parameters ....: $sSession - Session ID from _WD_CreateSession ; Return values .: Success - Element ID returned by web driver. ; Failure - Response from web driver and sets @error returned from _WD_ExecuteScript() ; Author ........: Danp2 ; Modified ......: mLipok ; Remarks .......: ; Related .......: _WD_ExecuteScript, _WD_LastHTTPResult ; Link ..........: https://stackoverflow.com/questions/24538450/get-element-currently-under-mouse-without-using-mouse-events ; Example .......: No ; =============================================================================================================================== Func _WD_GetMouseElement($sSession) Local Const $sFuncName = "_WD_GetMouseElement" Local $sScript = "return Array.from(document.querySelectorAll(':hover')).pop()" Local $sElement = _WD_ExecuteScript($sSession, $sScript, '', Default, $_WD_JSON_Element) Local $iErr = @error Return SetError(__WD_Error($sFuncName, $iErr, $sElement), 0, $sElement) EndFunc ;==>_WD_GetMouseElement ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WD_GetElementFromPoint ; Description ...: Retrieves reference to element at specified point. ; Syntax ........: _WD_GetElementFromPoint($sSession, $iX, $iY) ; Parameters ....: $sSession - Session ID from _WD_CreateSession ; $iX - an integer value ; $iY - an integer value ; Return values .: Success - Element ID returned by web driver. ; Failure - "" (empty string) and @error is set to $_WD_ERROR_RetValue ; Author ........: Danp2 ; Modified ......: mLipok ; Remarks .......: @extended is set to 1 if the browsing context changed during the function call ; Related .......: _WD_ExecuteScript, _WD_LastHTTPResult ; Link ..........: https://stackoverflow.com/questions/31910534/executing-javascript-elementfrompoint-through-selenium-driver/32574543#32574543 ; Example .......: No ; =============================================================================================================================== Func _WD_GetElementFromPoint($sSession, $iX, $iY) Local Const $sFuncName = "_WD_GetElementFromPoint" Local Const $sParameters = 'Parameters: X=' & $iX & ' Y=' & $iY Local $sResponse, $oJSON, $sElement = "" Local $sTagName, $sParams, $aCoords, $iFrame = 0, $oERect Local $sScript1 = "return document.elementFromPoint(arguments[0], arguments[1]);" Local $sScript2 = "return new Array(window.pageXOffset, window.pageYOffset);" Local $iErr = $_WD_ERROR_Success, $sResult, $bIsNull While True $sParams = $iX & ", " & $iY $sResponse = _WD_ExecuteScript($sSession, $sScript1, $sParams) If @error Then $iErr = $_WD_ERROR_RetValue ExitLoop EndIf $oJSON = Json_Decode($sResponse) $sElement = Json_Get($oJSON, $_WD_JSON_Element) If @error Then $sResult = Json_Get($oJSON, $_WD_JSON_Value) $bIsNull = (IsKeyword($sResult) = $KEYWORD_NULL) If Not $bIsNull Then $iErr = $_WD_ERROR_RetValue EndIf ExitLoop Else $sTagName = _WD_ElementAction($sSession, $sElement, "Name") If Not StringInStr($sTagName, "frame") Then ; check