-
Notifications
You must be signed in to change notification settings - Fork 17
Description
As discussed here , I do think there is a bug in Execute. I suspect that the sessionId and other path parameters such as (element)Id should not be keys of the "parameters" dictionary that is passed to SendRequest(method, UrlBase + path, parameters).
That applies in general to ALL commands, however with my limited testing experience it only seems to cause a fatal error when setting timeouts. The key sessionId seems to be redundant info in "parameters" passed to SendRequest as sessionId is already encoded in "path" by the time SendRequest is invoked.
Why this seems to only blow up for timeouts and not for other commands I tested is a mystery, but the commands that I have tried work fine WITHOUT the path keys sessionId and (element)Id in the parameter set passed to SendRequest. So... the most immediate (and kind of ugly!) fix is to only pass a parameter set to SendRequest that contains non-path parameters as in the following version of Execute (with optional raise input parameter):
Public Function Execute(driverCommand, Optional parameters As Dictionary = Nothing, Optional ByVal raise As Boolean = True)
Dim method As String: method = driverCommand(0)
Dim path As String: path = driverCommand(1)
If parameters Is Nothing Then
Set parameters = New Dictionary
End If
' Set default session id if session id is missing
If Not parameters.Exists("sessionId") Then
parameters.Add "sessionId", DefaultSessionId
End If
'Set path params to path, and save non-path params to nonPathParameters
Dim paramKey As Variant, nonPathParameters As New Dictionary
For Each paramKey In parameters
If InStr(path, "$" & paramKey) > 0 Then 'path parameter
path = Replace(path, "$" & paramKey, parameters(paramKey))
Else 'non-path parameter
nonPathParameters.Add paramKey, parameters(paramKey)
End If
Next paramKey
' Send request to selenium server
Dim resp As Dictionary
Set resp = SendRequest(method, UrlBase + path, nonPathParameters)
' Return value(s)
If IsNull(resp("value")) Then
Set Execute = New Dictionary 'executescript returns vbnullstring
ElseIf TypeName(resp("value")) = "Collection" Then
Set Execute = resp("value")
ElseIf VarType(resp("value")) = vbObject Then
If resp("value").Exists("error") And raise Then
'make this user optional
Err.raise 513, "WebDriver.Execute", JsonConverter.ConvertToJson(resp("value"))
Else
Set Execute = resp("value")
End If
Else
Execute = resp("value")
End If
End Function
After making the above change to Execute, I tested with the following:
Sub testfortimeouts()
Dim Driver As New WebDriver
Driver.Chrome
sesid1 = Driver.OpenBrowser
sesid2 = Driver.OpenBrowser
Driver.SetPageLoadTimeout 1000, sesid1
Driver.SetPageLoadTimeout 2000, sesid2
Debug.Print "s1", Driver.GetPageLoadTimeout(sesid1)
Debug.Print "s2", Driver.GetPageLoadTimeout(sesid2)
Driver.CloseBrowser sesid1
Driver.CloseBrowser sesid2
Driver.Shutdown
End Sub
The following is printed to immediate window:
s1 1000
s2 2000
I then ran a battery of different automation test subs and they all ran as expected.
Notes:
Maybe a cleaner more elegant fix to this bug is to pass two dictionaries to Execute - a path parameter dictionary and a non-path parameter dictionary.
This problem should also be corrected in the @ezagdd versions of ExecuteScript and IsElementPresent, although I have offered simplified versions of those (ExecuteScript and IsElementPresent) which call the raise-enabled Execute directly to reduce code redundancy and so, as a result, would not need to be corrected.