循环直到元素等于下拉菜单中的特定文本

时间:2019-01-02 17:44:06

标签: excel vba selenium-webdriver

我有以下代码

Do
    On Error Resume Next
    .FindElementById("ContentPlaceHolder1_DropDownListl2").AsSelect.SelectByText ("txt")
    On Error GoTo 0
Loop Until .FindElementById("ContentPlaceHolder1_DropDownListl2").AsSelect.SelectedOption.Text = "txt"

我有很多下拉列表,我使用相同的方法来处理它们,尽管我使用了On Error Resume Next,但有时还是会出错,我必须稍等一下,然后单击Resume以继续执行代码 我可以将其作为公共程序吗,因为我将这些行与其他元素一起使用很多? 以及如何避免错误?并同时获得我的目标,以便在下拉菜单中选择所需的文本

这是其中一个错误的快照 enter image description here

基于@QHarr的回复,我试图进行这样的公共过程

Sub WaitElement(driver As Selenium.WebDriver, sElement As SelectElement, txt As String)
Dim t           As Date
Const MAX_SEC   As Long = 30

With driver
    On Error Resume Next
        t = Timer
        Do
            DoEvents
            sElement.AsSelect.SelectByText txt
            If Timer - t > MAX_SEC Then Exit Do
        Loop Until sElement.AsSelect.SelectedOption.Text = txt
    On Error GoTo 0
End With

结束子

但是尝试以这种方式使用

WaitElement bot, .FindElementById("ContentPlaceHolder1_DropDownListnat"), ws.Range("B11").Value

我收到“运行时错误13”(类型不匹配)

应用名为“ TextIsSet”的UDF后,出现此错误 enter image description here

和同样的问题..如果我单击“调试”,然后单击“继续”,然后稍等片刻,则代码将恢复其工作

我也使用过此类行,但无济于事

        Do
    Loop While .FindElementsById("ContentPlaceHolder1_Dschool").Count = 0

我遇到了同样的错误,就是没有找到这样的元素

1 个答案:

答案 0 :(得分:1)

当某个动作导致DOM发生更改时,可能会发生这种情况。懒惰的方法是添加一个定时循环来尝试该元素,直到该错误消失或超时。您也可以尝试将“发生错误”转移到循环周围而不是循环内部,然后增加超时。这有点残酷,但没有可供测试的网页。

作为函数调用(感觉很丑,您可能会发现webElement不喜欢被传递):

Option Explicit
Public Sub test()
    Const MAX_WAIT_SEC As Long = 30
    'other code
    If TextIsSet(dropdown, expectedText, MAX_WAIT_SEC) Then

    End If

End Sub

Public Function TextIsSet(ByRef dropdown As Object, ByVal expectedText As String, ByVal MAX_WAIT_SEC As Long) As Boolean
    Dim t As Date
    On Error Resume Next
    t = Timer
    Do
        DoEvents
        dropdown.AsSelect.SelectByText expectedText
        If Timer - t > MAX_WAIT_SEC Then Exit Do
    Loop Until dropdown.AsSelect.SelectedOption.Text = expectedText
    If dropdown.AsSelect.SelectedOption.Text = expectedText Then
        TextIsSet = True
    Else
        TextIsSet = False
    End If
    On Error GoTo 0
End Function

我没有过时的元素测试用例,所以我只使用了下拉测试用例:

Option Explicit
Public Sub test()
    Const MAX_WAIT_SEC As Long = 30
    Dim d As WebDriver, expectedText As String, dropdown As Object
    'expectedText = "AL - Alabama"  ''Pass Case
     expectedText = "Bananaman" 'Fail Case
    Set d = New ChromeDriver

    With d       
        .get "https://tools.usps.com/zip-code-lookup.htm?byaddress"           
        Set dropdown = .FindElementById("tState")  
        'other code
        If TextIsSet(dropdown, expectedText, MAX_WAIT_SEC) Then
            Debug.Print "Tada"
        Else
            Debug.Print "Sigh"
        End If
        .Quit
    End With
End Sub

Public Function TextIsSet(ByRef dropdown As Object, ByVal expectedText As String, ByVal MAX_WAIT_SEC As Long) As Boolean
    Dim t As Date
    On Error Resume Next
    t = Timer
    Do
        DoEvents
        dropdown.AsSelect.SelectByText expectedText
        If Timer - t > MAX_WAIT_SEC Then Exit Do
    Loop Until dropdown.AsSelect.SelectedOption.Text = expectedText
    If dropdown.AsSelect.SelectedOption.Text = expectedText Then
        TextIsSet = True
    Else
        TextIsSet = False
    End If
    On Error GoTo 0
End Function