uezo / TinySeleniumVBA

A tiny Selenium wrapper written in pure VBA
MIT License
60 stars 17 forks source link

Add Method. Select operations #17

Open ghost opened 3 years ago

ghost commented 3 years ago

以前にお送りしたソース内の 『 Select operations 』 に対してメッソドの追加変更です。 丸ごと置き換えて頂いた方がよいです。

【『 Select operations 』 に対する追加変更したメソッド】  [セレクトタグに属する全オプションリスト取得]  追加 SelectTagOptions

 [選択する]  変更 SelectByValue    以前のものは内容が SelectByVisibleText であるべきだったので、あるべきに見直しました。  追加 SelectByVisibleText  以前の SelectByValue の内容です。Private Function FindChildElement を吸収しています。  追加 SelectByIndex

 [選択されているオプション]  同じ SelectedOptionText  追加 AllSelectedOptions

 [未選択にする]  追加 DeSelectAll  追加 DeSelectByValue  追加 DeSelectByVisibleText  追加 DeSelectByIndex

【ソース】  WebDriver.cls

' ==========================================================================
' Select operations
' ==========================================================================

' Select By Value               '2021/6/19 add ishi -> 2021/08/10 chg ishi
Public Function SelectByValue(value As String, _
                              ByVal ElementId As String, _
                              Optional ByVal sessionId As String = vbNullString)
    Dim data  As New Dictionary
    data.Add "using", "css selector"
    data.Add "value", "option[value =" & """" & value & """" & "]"
    data.Add "id", ElementId
    If sessionId <> vbNullString Then
        data.Add "sessionId", sessionId
    End If

    Dim elmId As WebElement
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, data)(ELEMENT_KEY), sessionId)
    If IsElementSelected(elmId.ElementId_) = "False" Then
        Click elmId.ElementId_
    End If
End Function

' Select By Visible Text        '2021/8/10 add ishi
Public Function SelectByVisibleText(text As String, _
                                    ByVal ElementId As String, _
                                    Optional ByVal sessionId As String = vbNullString)
    Dim data  As New Dictionary
    data.Add "using", "xpath"
    data.Add "value", ".//option[normalize-space(.) = " & """" & text & """" & "]"
    data.Add "id", ElementId
    If sessionId <> vbNullString Then
        data.Add "sessionId", sessionId
    End If

    Dim elmId As WebElement
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, data)(ELEMENT_KEY), sessionId)
    If IsElementSelected(elmId.ElementId_) = "False" Then
        Click elmId.ElementId_
    End If
End Function

' Select By Index               '2021/8/10 add ishi
Public Function SelectByIndex(index As Integer, _
                              ByVal ElementId As String, _
                              Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)

    ' index check
    Dim Script As String
    Script = getAttribute_js
    Dim optdata   As New Dictionary
    If sessionId <> vbNullString Then
        optdata.Add "sessionId", sessionId
    End If

    Dim args As Variant
    Dim indexno As String
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        optdata.Add "ELEMENT", elmIds(i).ElementId_
        optdata.Add ELEMENT_KEY, elmIds(i).ElementId_
        args = Array(optdata, "index")
        indexno = ExecuteScript(Script, args)
        If indexno = CStr(index) Then
            If IsElementSelected(elmIds(i).ElementId_) = "False" Then
                Click elmIds(i).ElementId_
            End If
            Exit For
        End If
        optdata.Remove "ELEMENT"
        optdata.Remove ELEMENT_KEY
    Next
End Function

' Select Tag's Options          '2021/8/10 add ishi
Public Function SelectTagsOptions(ByVal ElementId As String, _
                                  Optional ByVal sessionId As String = vbNullString) As String()
    Dim elmTags() As WebElement
    elmTags = FindElements(By.TagName, "option", ElementId)
    Dim ret() As String
    Dim i As Integer
    ret = VBA.Split(VBA.vbNullString)    'Create Empty Array
    For i = 0 To UBound(elmTags)
        ReDim Preserve ret(i)
        ret(i) = elmTags(i).GetText
    Next
    SelectTagsOptions = ret
End Function

' All Selected Options          '2021/8/10 add ishi
Public Function AllSelectedOptions(ByVal ElementId As String, _
                                   Optional ByVal sessionId As String = vbNullString) As String()
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)
    Dim ret() As String
    Dim i As Integer
    Dim j As Integer
    j = 0
    ret = VBA.Split(VBA.vbNullString)    'Create Empty Array
    For i = 0 To UBound(elmIds)
        If IsElementSelected(elmIds(i).ElementId_) = "True" Then
            ReDim Preserve ret(j)
            ret(j) = elmIds(i).GetText
            j = j + 1
        End If
    Next i
    AllSelectedOptions = ret
End Function

' First Selected Option Text    '2021/6/19 add ishi
Public Function SelectedOptionText(ByVal ElementId As String, _
                                   Optional ByVal sessionId As String = vbNullString) As String
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        If IsElementSelected(elmIds(i).ElementId_) = "True" Then
            SelectedOptionText = elmIds(i).GetText
            Exit Function
        End If
    Next i
    SelectedOptionText = ""
End Function

' DeSelect All                  '2021/8/10 add ishi
Public Function DeSelectAll(ByVal ElementId As String, _
                            Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        If IsElementSelected(elmIds(i).ElementId_) = "True" Then
            Click elmIds(i).ElementId_
        End If
    Next i
End Function

' DeSelect By Value             '2021/08/10 add ishi
Public Function DeSelectByValue(value As String, _
                                ByVal ElementId As String, _
                                Optional ByVal sessionId As String = vbNullString)
    Dim data  As New Dictionary
    data.Add "using", "css selector"
    data.Add "value", "option[value =" & """" & value & """" & "]"
    data.Add "id", ElementId
    If sessionId <> vbNullString Then
        data.Add "sessionId", sessionId
    End If

    Dim elmId As WebElement
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, data)(ELEMENT_KEY), sessionId)
    If IsElementSelected(elmId.ElementId_) = "True" Then
        Click elmId.ElementId_
    End If
End Function

' DeSelect By Visible Text      '2021/8/10 add ishi
Public Function DeSelectByVisibleText(text As String, _
                                    ByVal ElementId As String, _
                                    Optional ByVal sessionId As String = vbNullString)
    Dim data  As New Dictionary
    data.Add "using", "xpath"
    data.Add "value", ".//option[normalize-space(.) = " & """" & text & """" & "]"
    data.Add "id", ElementId
    If sessionId <> vbNullString Then
        data.Add "sessionId", sessionId
    End If

    Dim elmId As WebElement
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, data)(ELEMENT_KEY), sessionId)
    If IsElementSelected(elmId.ElementId_) = "True" Then
        Click elmId.ElementId_
    End If
End Function

' DeSelect By Index             '2021/8/10 add ishi
Public Function DeSelectByIndex(index As Integer, _
                                ByVal ElementId As String, _
                                Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)

    ' index check
    Dim Script As String
    Script = getAttribute_js
    Dim optdata   As New Dictionary
    If sessionId <> vbNullString Then
        optdata.Add "sessionId", sessionId
    End If

    Dim args As Variant
    Dim indexno As String
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        optdata.Add "ELEMENT", elmIds(i).ElementId_
        optdata.Add ELEMENT_KEY, elmIds(i).ElementId_
        args = Array(optdata, "index")
        indexno = ExecuteScript(Script, args)
        If indexno = CStr(index) Then
            If IsElementSelected(elmIds(i).ElementId_) = "True" Then
                Click elmIds(i).ElementId_
            End If
            Exit For
        End If
        optdata.Remove "ELEMENT"
        optdata.Remove ELEMENT_KEY
    Next
End Function

' Fine Child Elements           '2021/6/19 add ishi
Private Function FindChildElements(ByVal ElementId As String, _
                                   Optional ByVal sessionId As String = vbNullString) As WebElement()
    Dim data    As New Dictionary
    data.Add "using", "css selector"
    data.Add "value", "option"
    data.Add "id", ElementId
    If sessionId <> vbNullString Then
        data.Add "sessionId", sessionId
    End If

    Dim elements
    Set elements = Execute(CMD_FIND_CHILD_ELEMENTS, data)

    ' To array
    Dim ret() As WebElement
    Dim i As Integer
    For i = 0 To elements.Count - 1         'elements is Collection, not array
        ReDim Preserve ret(i)
        Set ret(i) = ToWebElement(elements(i + 1)(ELEMENT_KEY), sessionId)
    Next

    ' Return element ids
    FindChildElements = ret
End Function

' Is Element Selected           '2021/6/19 add ishi
Private Function IsElementSelected(ByVal ElementId As String, _
                                   Optional ByVal sessionId As String = vbNullString) As String
    Dim data    As New Dictionary
    data.Add "id", ElementId
    If sessionId <> vbNullString Then
        data.Add "sessionId", sessionId
    End If
    IsElementSelected = Execute(CMD_IS_ELEMENT_SELECTED, data)
End Function

 WebElement.cls

' ==========================================================================
' Select operations
' ==========================================================================

' Select By Value                   '2021/6/22 add ishi
Public Function SelectByValue(ByVal value As String)
    Driver_.SelectByValue value, ElementId_, SessionId_
End Function

' Select By Visible Text            '2021/8/10 add ishi
Public Function SelectByVisibleText(ByVal text As String)
    Driver_.SelectByVisibleText text, ElementId_, SessionId_
End Function

' Select By Index                   '2021/8/10 add ishi
Public Function SelectByIndex(ByVal index As Integer)
    Driver_.SelectByIndex index, ElementId_, SessionId_
End Function

' Select Tag's Options              '2021/8/10 add ishi
Public Function SelectTagsOptions() As String()
    SelectTagsOptions = Driver_.SelectTagsOptions(ElementId_, SessionId_)
End Function

' All Selected Options              '2021/8/10 add ishi
Public Function AllSelectedOptions() As String()
    AllSelectedOptions = Driver_.AllSelectedOptions(ElementId_, SessionId_)
End Function

' First Selected Option Text        '2021/6/22 add ishi
Public Function SelectedOptionText() As String
    SelectedOptionText = Driver_.SelectedOptionText(ElementId_, SessionId_)
End Function

' DeSelect All                      '2021/8/10 add ishi
Public Function DeSelectAll() As String()
    Driver_.DeSelectAll ElementId_, SessionId_
End Function

' DeSelect By Value                 '2021/8/10 add ishi
Public Function DeSelectByValue(ByVal value As String)
    Driver_.DeSelectByValue value, ElementId_, SessionId_
End Function

' DeSelect By Visible Text          '2021/8/10 add ishi
Public Function DeSelectByVisibleText(ByVal text As String)
    Driver_.DeSelectByVisibleText text, ElementId_, SessionId_
End Function

' DeSelect By Index                 '2021/8/10 add ishi
Public Function DeSelectByIndex(ByVal index As Integer)
    Driver_.DeSelectByIndex index, ElementId_, SessionId_
End Function
ghost commented 3 years ago

ExecuteScriptを直接呼び出す際のElementIDへの配慮を加えた『ExecuteScript』 (Method. ExecuteScript #24 commented 1)に対応した『SelectByIndex』『DeSelectByIndex』です。

【ソース】  WebDriver.cls

' Select By Index               '2021/8/10 add ishi -> 2021/9/30 chg ishi
Public Function SelectByIndex(index As Integer, _
                              ByVal ElementId As String, _
                              Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)

    ' index check
    Dim Script As String
    Script = getAttribute_js
    Dim optdata   As New Dictionary
    If sessionId <> vbNullString Then
        optdata.Add "sessionId", sessionId
    End If

    Dim args As Variant
    Dim indexno As String
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        indexno = ExecuteScript(Script, "index", elmIds(i).ElementId_)
        If indexno = CStr(index) Then
            If IsElementSelected(elmIds(i).ElementId_) = "False" Then
                Click elmIds(i).ElementId_
            End If
            Exit For
        End If
    Next
End Function
' DeSelect By Index             '2021/8/10 add ishi -> 2021/9/30 chg ishi
Public Function DeSelectByIndex(index As Integer, _
                                ByVal ElementId As String, _
                                Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)

    ' index check
    Dim Script As String
    Script = getAttribute_js
    Dim optdata   As New Dictionary
    If sessionId <> vbNullString Then
        optdata.Add "sessionId", sessionId
    End If

    Dim args As Variant
    Dim indexno As String
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        indexno = ExecuteScript(Script, "index", elmIds(i).ElementId_)
        If indexno = CStr(index) Then
            If IsElementSelected(elmIds(i).ElementId_) = "True" Then
                Click elmIds(i).ElementId_
            End If
            Exit For
        End If
    Next
End Function
ghost commented 3 years ago

Script = getAttribute_js がエラーとなっていた事に対する対応版です。

【ソース】  WebDriver.cls

' Select By Index               '2021/8/10 add ishi -> 2021/9/30 chg ishi -> 2021/10/24 chg ishi
Public Function SelectByIndex(index As Integer, _
                              ByVal ElementId As String, _
                              Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)

    ' index check
    Dim Script As String
    Script = "return arguments[0].selectedIndex = " & CStr(index)
    Dim optdata   As New Dictionary
    If sessionId <> vbNullString Then
        optdata.Add "sessionId", sessionId
    End If

    Dim args As Variant
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        If i = index Then
            If IsElementSelected(elmIds(index).ElementId_) = "False" Then
                ExecuteScript Script, vbNullString, elmIds(index).ElementId_
                Click elmIds(index).ElementId_
                Exit For
            End If
        End If
    Next
End Function
' DeSelect By Index             '2021/8/10 add ishi -> 2021/9/30 chg ishi -> 2021/10/24 chg ishi
Public Function DeSelectByIndex(index As Integer, _
                                ByVal ElementId As String, _
                                Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)

    ' index check
    Dim Script As String
    Script = "return arguments[1].selectedIndex = " & CStr(index)
    Dim optdata   As New Dictionary
    If sessionId <> vbNullString Then
        optdata.Add "sessionId", sessionId
    End If

    Dim args As Variant
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        If i = index Then
            If IsElementSelected(elmIds(index).ElementId_) = "True" Then
                ExecuteScript Script, vbNullString, elmIds(index).ElementId_
                Click elmIds(index).ElementId_
                Exit For
            End If
        End If
    Next
End Function
ghost commented 2 years ago

WebDriver.cls の SelectByIndex と DeSelectAll のバグ修正版です。 Fixed bugs of SelectByIndex and DeSelectAll of WebDriver.cls.

Public Function SelectByIndex(index As Integer, _
                              ByVal ElementId As String, _
                              Optional ByVal sessionId As String = vbNullString)
    Dim optdata   As New Dictionary
    If sessionId <> vbNullString Then
        optdata.Add "sessionId", sessionId
    End If
    Me.Focus ElementId
    ExecuteScript "arguments[0].options[" & CStr(index) & "].selected = true;", vbNullString, ElementId
End Function
Public Function DeSelectAll(ByVal ElementId As String, _
                            Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)
    Dim i As Integer
    Me.Focus ElementId
    For i = 0 To UBound(elmIds)
        ExecuteScript "arguments[0].options[" & CStr(i) & "].selected = false;", vbNullString, ElementId
    Next i
End Function

    WebDriver.cls に SelectAll を追加しました。 Add Method SelectAll of WebDriver.cls.

Public Function SelectAll(ByVal ElementId As String, _
                          Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)
    Dim i As Integer
    Me.Focus ElementId
    For i = 0 To UBound(elmIds)
        ExecuteScript "arguments[0].options[" & CStr(i) & "].selected = true;", vbNullString, ElementId
    Next i
End Function

WebElement.cls に SelectAll を追加しました。 Add Method SelectAll of WebElement.cls.

Public Function SelectAll() As String()
    Driver_.SelectAll ElementId_, SessionId_
End Function

    WebDriver.cls の DeSelectAll を見直しました。 Modify Method DeSelectAll of WebDriver.cls.

Public Function DeSelectAll(ByVal ElementId As String, _
                            Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId)
    Dim i As Integer
    Me.Focus ElementId
    For i = 0 To UBound(elmIds)
        ExecuteScript "arguments[0].options[" & CStr(i) & "].selected = false;", vbNullString, ElementId
    Next i
End Function
GCuser99 commented 2 years ago

Thanks @ezagdd. Shouldn't sessionId parameter be passed to all subordinate methods (Focus, FindChildElements, and ExecuteScript)? Also the optdata dictionary is not used (not needed?) in SelectByIndex...

GCuser99 commented 2 years ago

same issues with DeSelectByIndex...

GCuser99 commented 2 years ago

Also, sessionId needs to be passed to IsElementSelected and Click in SelectByValue and SelectByVisibleText. Same with FindElements in SelectTagsOptions. FindChildElements and IsElementSelected in AllSelectedOptions. FindChildElements and IsElementSelected in SelectedOptionText IsElementSelected and Click in DeSelectByValue IsElementSelected and Click in DeSelectByVisibleText

ghost commented 2 years ago

ソースレビューありがとう。 sessionId 指定漏れを修正しました。 Thank you for the source review. Fixed the sessionId specification omission.

' Select All
Public Function SelectAll(ByVal ElementId As String, _
                          Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId, sessionId)
    Dim i As Integer
    Focus ElementId, sessionId
    For i = 0 To UBound(elmIds)
        ExecuteScript "arguments[0].options[" & CStr(i) & "].selected = true;", vbNullString, ElementId, sessionId
    Next i
End Function

' Select By Value
Public Function SelectByValue(ByVal value As String, _
                              ByVal ElementId As String, _
                              Optional ByVal sessionId As String = vbNullString)
    Dim Data As New Dictionary
    Data.Add "using", "css selector"
    Data.Add "value", "option[value =" & """" & value & """" & "]"
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If
    Dim elmId As WebElement
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, Data)("value")(ELEMENT_KEY), sessionId)
    If IsElementSelected(elmId.ElementId_, sessionId) = "False" Then
        elmId.Click
    End If
End Function

' Select By Visible Text
Public Function SelectByVisibleText(ByVal text As String, _
                                    ByVal ElementId As String, _
                                    Optional ByVal sessionId As String = vbNullString)
    Dim Data As New Dictionary
    Data.Add "using", "xpath"
    Data.Add "value", ".//option[normalize-space(.) = " & """" & text & """" & "]"
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If
    Dim elmId As WebElement
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, Data)("value")(ELEMENT_KEY), sessionId)
    If IsElementSelected(elmId.ElementId_, sessionId) = "False" Then
        elmId.Click
    End If
End Function

' Select By Index
Public Function SelectByIndex(index As Integer, _
                              ByVal ElementId As String, _
                              Optional ByVal sessionId As String = vbNullString)
    Focus ElementId, sessionId
    ExecuteScript "arguments[0].options[" & CStr(index) & "].selected = true;", vbNullString, ElementId, sessionId
End Function

' Select Tag's Options
Public Function SelectTagsOptions(ByVal ElementId As String, _
                                  Optional ByVal sessionId As String = vbNullString) As String()
    Dim elmTags() As WebElement
    elmTags = FindElements(By.TagName, "option", ElementId, sessionId)
    Dim Ret() As String
    Dim i As Integer
    Ret = VBA.Split(VBA.vbNullString)    'Create Empty Array
    For i = 0 To UBound(elmTags)
        ReDim Preserve Ret(i)
        Ret(i) = elmTags(i).GetText
    Next
    SelectTagsOptions = Ret
End Function

' All Selected Options
Public Function AllSelectedOptions(ByVal ElementId As String, _
                                   Optional ByVal sessionId As String = vbNullString) As String()
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId, sessionId)
    Dim Ret() As String
    Dim i As Integer
    Dim j As Integer
    j = 0
    Ret = VBA.Split(VBA.vbNullString)    'Create Empty Array
    For i = 0 To UBound(elmIds)
        If IsElementSelected(elmIds(i).ElementId_, sessionId) = "True" Then
            ReDim Preserve Ret(j)
            Ret(j) = elmIds(i).GetText
            j = j + 1
        End If
    Next i
    AllSelectedOptions = Ret
End Function

' First Selected Option Text
Public Function SelectedOptionText(ByVal ElementId As String, _
                                   Optional ByVal sessionId As String = vbNullString) As String
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId, sessionId)
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        If IsElementSelected(elmIds(i).ElementId_, sessionId) = "True" Then
            SelectedOptionText = elmIds(i).GetText
            Exit Function
        End If
    Next i
    SelectedOptionText = ""
End Function

' DeSelect All
Public Function DeSelectAll(ByVal ElementId As String, _
                            Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId, sessionId)
    Focus ElementId, sessionId
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        ExecuteScript "arguments[0].options[" & CStr(i) & "].selected = false;", vbNullString, ElementId, sessionId
    Next i
End Function

' DeSelect By Value
Public Function DeSelectByValue(ByVal value As String, _
                                ByVal ElementId As String, _
                                Optional ByVal sessionId As String = vbNullString)
    Dim Data As New Dictionary, elmId As WebElement
    Data.Add "using", "css selector"
    Data.Add "value", "option[value =" & """" & value & """" & "]"
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, Data)("value")(ELEMENT_KEY), sessionId)
    If IsElementSelected(elmId.ElementId_, sessionId) = "True" Then
        elmId.Click
    End If
End Function

' DeSelect By Visible Text
Public Function DeSelectByVisibleText(ByVal text As String, _
                                      ByVal ElementId As String, _
                                      Optional ByVal sessionId As String = vbNullString)
    Dim Data As New Dictionary, elmId As WebElement
    Data.Add "using", "xpath"
    Data.Add "value", ".//option[normalize-space(.) = " & """" & text & """" & "]"
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, Data)("value")(ELEMENT_KEY), sessionId)
    If IsElementSelected(elmId.ElementId_, sessionId) = "True" Then
        elmId.Click
    End If
End Function

' DeSelect By Index
Public Function DeSelectByIndex(index As Integer, _
                                ByVal ElementId As String, _
                                Optional ByVal sessionId As String = vbNullString)
    Focus ElementId, sessionId
    ExecuteScript "arguments[0].options[" & CStr(index) & "].selected = false;", vbNullString, ElementId, sessionId
End Function
GCuser99 commented 2 years ago

Awesome thanks for your effort!

GCuser99 commented 2 years ago

Also consider changing return type of IsElementSelected to boolean?

GCuser99 commented 2 years ago

Also suggest to rename method IsElementSelected to IsSelected... (?)

ghost commented 2 years ago

Rename method IsElementSelected to IsSelected. Return type of IsElementSelected to boolean. Change the scope of IsSelected to public and add it to WebElement.

WdbDriver.cls

' ==========================================================================
' Select operations
' ==========================================================================

' Select All                    '2022/1/8 chg ishi
Public Function SelectAll(ByVal ElementId As String, _
                          Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId, sessionId)
    Dim i As Integer
    Focus ElementId, sessionId
    For i = 0 To UBound(elmIds)
        ExecuteScript "arguments[0].options[" & CStr(i) & "].selected = true;", vbNullString, ElementId, sessionId
    Next i
End Function

' Select By Value               '2022/1/10 chg ishi
Public Function SelectByValue(ByVal value As String, _
                              ByVal ElementId As String, _
                              Optional ByVal sessionId As String = vbNullString)
    Dim Data As New Dictionary
    Data.Add "using", "css selector"
    Data.Add "value", "option[value =" & """" & value & """" & "]"
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If
    Dim elmId As WebElement
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, Data)("value")(ELEMENT_KEY), sessionId)
    If Not IsSelected(elmId.ElementId_, sessionId) Then
        elmId.Click
    End If
End Function

' Select By Visible Text        '2022/1/10 chg ishi
Public Function SelectByVisibleText(ByVal text As String, _
                                    ByVal ElementId As String, _
                                    Optional ByVal sessionId As String = vbNullString)
    Dim Data As New Dictionary
    Data.Add "using", "xpath"
    Data.Add "value", ".//option[normalize-space(.) = " & """" & text & """" & "]"
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If
    Dim elmId As WebElement
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, Data)("value")(ELEMENT_KEY), sessionId)
    If Not IsSelected(elmId.ElementId_, sessionId) Then
        elmId.Click
    End If
End Function

' Select By Index               '2022/1/8 chg ishi
Public Function SelectByIndex(index As Integer, _
                              ByVal ElementId As String, _
                              Optional ByVal sessionId As String = vbNullString)
    Focus ElementId, sessionId
    ExecuteScript "arguments[0].options[" & CStr(index) & "].selected = true;", vbNullString, ElementId, sessionId
End Function

' Select Tag's Options          '2022/1/8 chg ishi
Public Function SelectTagsOptions(ByVal ElementId As String, _
                                  Optional ByVal sessionId As String = vbNullString) As String()
    Dim elmTags() As WebElement
    elmTags = FindElements(By.TagName, "option", ElementId, sessionId)
    Dim Ret() As String
    Dim i As Integer
    Ret = VBA.Split(VBA.vbNullString)    'Create Empty Array
    For i = 0 To UBound(elmTags)
        ReDim Preserve Ret(i)
        Ret(i) = elmTags(i).GetText
    Next
    SelectTagsOptions = Ret
End Function

' All Selected Options          '2022/1/10 chg ishi
Public Function AllSelectedOptions(ByVal ElementId As String, _
                                   Optional ByVal sessionId As String = vbNullString) As String()
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId, sessionId)
    Dim Ret() As String
    Dim i As Integer
    Dim j As Integer
    j = 0
    Ret = VBA.Split(VBA.vbNullString)    'Create Empty Array
    For i = 0 To UBound(elmIds)
        If IsSelected(elmIds(i).ElementId_, sessionId) Then
            ReDim Preserve Ret(j)
            Ret(j) = elmIds(i).GetText
            j = j + 1
        End If
    Next i
    AllSelectedOptions = Ret
End Function

' First Selected Option Text    '2022/1/10 chg ishi
Public Function SelectedOptionText(ByVal ElementId As String, _
                                   Optional ByVal sessionId As String = vbNullString) As String
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId, sessionId)
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        If IsSelected(elmIds(i).ElementId_, sessionId) Then
            SelectedOptionText = elmIds(i).GetText
            Exit Function
        End If
    Next i
    SelectedOptionText = ""
End Function

' DeSelect All                  '2022/1/8 Chg ishi
Public Function DeSelectAll(ByVal ElementId As String, _
                            Optional ByVal sessionId As String = vbNullString)
    Dim elmIds() As WebElement
    elmIds = FindChildElements(ElementId, sessionId)
    Focus ElementId, sessionId
    Dim i As Integer
    For i = 0 To UBound(elmIds)
        ExecuteScript "arguments[0].options[" & CStr(i) & "].selected = false;", vbNullString, ElementId, sessionId
    Next i
End Function

' DeSelect By Value             '2022/1/10 chg ishi
Public Function DeSelectByValue(ByVal value As String, _
                                ByVal ElementId As String, _
                                Optional ByVal sessionId As String = vbNullString)
    Dim Data As New Dictionary, elmId As WebElement
    Data.Add "using", "css selector"
    Data.Add "value", "option[value =" & """" & value & """" & "]"
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, Data)("value")(ELEMENT_KEY), sessionId)
    If IsSelected(elmId.ElementId_, sessionId) Then
        elmId.Click
    End If
End Function

' DeSelect By Visible Text      '2022/1/10 chg ishi
Public Function DeSelectByVisibleText(ByVal text As String, _
                                      ByVal ElementId As String, _
                                      Optional ByVal sessionId As String = vbNullString)
    Dim Data As New Dictionary, elmId As WebElement
    Data.Add "using", "xpath"
    Data.Add "value", ".//option[normalize-space(.) = " & """" & text & """" & "]"
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If
    Set elmId = ToWebElement(Execute(CMD_FIND_CHILD_ELEMENT, Data)("value")(ELEMENT_KEY), sessionId)
    If IsSelected(elmId.ElementId_, sessionId) Then
        elmId.Click
    End If
End Function

' DeSelect By Index             '2022/1/8 chg ishi
Public Function DeSelectByIndex(index As Integer, _
                                ByVal ElementId As String, _
                                Optional ByVal sessionId As String = vbNullString)
    Focus ElementId, sessionId
    ExecuteScript "arguments[0].options[" & CStr(index) & "].selected = false;", vbNullString, ElementId, sessionId
End Function

' Is Selected                   '2022/1/10 chg
Public Function IsSelected(ByVal ElementId As String, _
                           Optional ByVal sessionId As String = vbNullString) As Boolean
    Dim Data As New Dictionary
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If
    If Execute(CMD_IS_ELEMENT_SELECTED, Data)("value") = "True" Then
        IsSelected = True
    Else
        IsSelected = False
    End If
End Function

' Fine Child Elements           '2022/1/3 chg
Private Function FindChildElements(ByVal ElementId As String, _
                                   Optional ByVal sessionId As String = vbNullString) As WebElement()
    Dim Data As New Dictionary
    Dim elements
    Dim Ret() As WebElement
    Dim i As Integer

    Data.Add "using", "css selector"
    Data.Add "value", "option"
    Data.Add "id", ElementId
    If sessionId <> vbNullString Then
        Data.Add "sessionId", sessionId
    End If

    Set elements = Execute(CMD_FIND_CHILD_ELEMENTS, Data)("value")

    ' To array
    For i = 0 To elements.Count - 1         'elements is Collection, not array
        ReDim Preserve Ret(i)
        Set Ret(i) = ToWebElement(elements(i + 1)(ELEMENT_KEY), sessionId)
    Next

    ' Return element ids
    FindChildElements = Ret
End Function

WebElement.cls

' ==========================================================================
' Select operations
' ==========================================================================

' Select All                        '2022/1/6 add ishi
Public Function SelectAll() As String()
    Driver_.SelectAll ElementId_, SessionId_
End Function

' Select By Value                   '2021/6/22 add ishi
Public Function SelectByValue(ByVal value As String)
    Driver_.SelectByValue value, ElementId_, SessionId_
End Function

' Select By Visible Text            '2021/8/10 add ishi
Public Function SelectByVisibleText(ByVal text As String)
    Driver_.SelectByVisibleText text, ElementId_, SessionId_
End Function

' Select By Index                   '2021/8/10 add ishi
Public Function SelectByIndex(ByVal index As Integer)
    Driver_.SelectByIndex index, ElementId_, SessionId_
End Function

' Select Tag's Options              '2021/8/10 add ishi
Public Function SelectTagsOptions() As String()
    SelectTagsOptions = Driver_.SelectTagsOptions(ElementId_, SessionId_)
End Function

' All Selected Options              '2021/8/10 add ishi
Public Function AllSelectedOptions() As String()
    AllSelectedOptions = Driver_.AllSelectedOptions(ElementId_, SessionId_)
End Function

' First Selected Option Text        '2021/6/22 add ishi
Public Function SelectedOptionText() As String
    SelectedOptionText = Driver_.SelectedOptionText(ElementId_, SessionId_)
End Function

' DeSelect All                      '2021/8/10 add ishi
Public Function DeSelectAll() As String()
    Driver_.DeSelectAll ElementId_, SessionId_
End Function

' DeSelect By Value                 '2021/8/10 add ishi
Public Function DeSelectByValue(ByVal value As String)
    Driver_.DeSelectByValue value, ElementId_, SessionId_
End Function

' DeSelect By Visible Text          '2021/8/10 add ishi
Public Function DeSelectByVisibleText(ByVal text As String)
    Driver_.DeSelectByVisibleText text, ElementId_, SessionId_
End Function

' DeSelect By Index                 '2021/8/10 add ishi
Public Function DeSelectByIndex(ByVal index As Integer)
    Driver_.DeSelectByIndex index, ElementId_, SessionId_
End Function

' IsSelected                        '2022/1/10 add ishi
Public Function IsSelected() As Boolean
    IsSelected = Driver_.IsSelected(ElementId_, SessionId_)
End Function