-
Notifications
You must be signed in to change notification settings - Fork 25
Description
During last days I kept an always-on SeleniumVBA loop running with a 2000ms sleep each run.
Each morning, I found the script hung.
After the nth night crash, I investigated and found that it was simply waiting for the VBA.Timer to reach an overlimit number equivalent to 24:00:02 that could never reach because at midnight VBA.Timer resets to 0.
I thought about a couple of solutions to this bug:
- adding the VBA.Date to VBA.Timer: CLng(VBA.Date) + (CDbl(VBA.Timer) / 86400)
- going with the Windows API timers, that never reset
Since I already fine-tuned my all-purpose Sleep procedure for my master library, reaching my goal of <0.0% CPU usage, DoEvents, accuracy +-<10ms, I thought it would be a good idea to move it to the WebShared module for use by SeleniumVBA too, as in my last pull request.
I was also about to modify your WaitUntilReady procedure:
'@Description("Waits until element is interactable")
Public Function WaitUntilReady(element As WebElement, Optional ByVal maxWaitTimeMS As Long = 30000) As WebElement
'waits until element is interactable, returns the input element for further action
'such as "Click" on same line
'see https://www.w3.org/TR/webdriver/#element-displayedness
Dim startTime As Single
Dim nowTime As Single
Dim endTime As Single
startTime = VBA.Timer
nowTime = startTime
endTime = startTime + maxWaitTimeMS / 1000#
Do While nowTime < endTime
If element.IsDisplayed Then Exit Do
nowTime = VBA.Timer()
Dim elapsedTime As Single
If nowTime < startTime Then
endTime = endTime - elapsedTime
startTime = 0
End If
elapsedTime = nowTime - startTime
DoEvents 'yield to other processes.
Loop
Set WaitUntilReady = element
End Function
using the Windows API functions, like this:
'@Description("Waits until element is interactable")
Public Function WaitUntilReady(element As WebElement, Optional ByVal maxWaitTimeMS As Long = 30000) As WebElement
'waits until element is interactable, returns the input element for further action
'such as "Click" on same line
'see https://www.w3.org/TR/webdriver/#element-displayedness
Dim cTimeStart As Currency, cTimeNow As Currency
Dim dTimeElapsed As Currency, cMaxWaitTimeMS As Currency
getTime cTimeStart
Static cPerSecond As Currency
If cPerSecond = 0 Then getFrequency cPerSecond
cMaxWaitTimeMS = CCur(maxWaitTimeMS) * (cPerSecond / 1000)
Do
If element.IsDisplayed Then Exit Do
getTime cTimeNow
DoEvents 'yield to other processes
Loop Until (cTimeNow - cTimeStart) >= cMaxWaitTimeMS
Set WaitUntilReady = element
End Function
or at least using the VBA.Date to VBA.Timer solution,
but I didn't understand its "If nowTime < startTime" branch:
I can only think of a nowTime that is less than startTime when midnight passes, however I can't understand what the following lines accomplish. They don't seem to approach the midnight issue.
So, I leave my pull request and this last function modification for your review @GCuser99.