5

I am navigating a web application that will often throw an error if there is an attempt to click an element before it can be interacted with.

When using Selenium WebDriver (java), I can easily work around the problem:

 WebDriverWait wait = new WebDriverWait(driver, 15);

 wait.until(ExpectedConditions.elementToBeClickable(By.id("element")));

However, I am trying to write the script in VBA utilizing the Selenium type library, and, despite trying numerous different ways, the only success I am having is:

webdriver.wait

which I have been told should be avoided if at all possible. If someone can advise how to translate my java into VBA, or provide any other solution, I would be extremely grateful.

Dragonthoughts
  • 2,180
  • 8
  • 25
  • 28
ex-expat
  • 71
  • 1
  • 2
  • 8
  • Check out [this link](https://stackoverflow.com/questions/50238062/unable-to-check-for-availability-of-any-element-removing-hardcoded-delay) to find the solution for `Explicit Wait` within selenium vba binding. – MITHU May 08 '18 at 21:05
  • if you showed the relevant HTML it would make advising on possible solutions easier. – QHarr Jul 04 '18 at 19:47
  • I can add a wait clickable method for vba that executes is js in browser if you want? – QHarr Dec 19 '19 at 10:33

5 Answers5

7

You might try looping until the element has been set correctly with a time out to ensure you can't go into an infinite loop. The danger with the accepted answer is there is no way to escape the loop if not found.

Dim t As Date, ele As Object
t = Timer
Do
    DoEvents
    On Error Resume Next
    Set ele = .FindElementById("element")
    On Error GoTo 0
    If Timer - t = 10 Then Exit Do '<==To avoid infinite loop
Loop While ele Is Nothing

Note: User @florentbr wrote a js wait clickable function to be executed via Selenium Basic. Example in this SO answer.

QHarr
  • 83,427
  • 12
  • 54
  • 101
2

The selenium plugin for VBA is unofficial and doesn't support this feature.

You can work around this by using onError to retry the action that is producing an error until it succeeds or times out:

Sub test
    OnError GoTo Retry
        webDriver.findElementById("element")
    Exit Sub

    Dim i as integer
    :Retry
        webDriver.Wait(500)
        i = i + 1
        if i = 20 then onerror go to 0
    Resume
end sub
TZubiri
  • 886
  • 11
  • 30
1

In vba you can use Implicit wait "driver.Timeouts.ImplicitWait = 10 'Timeunits 'seconds" it will wait maximum limit if the element is found before the set time it will process further.

  • Hello @Prashant Mallick. How can you catch if element was not found after 10 seconds in VBA? Can you please help? – Jacek Antek Sep 13 '20 at 18:04
1

You can use a variation in the old wait system used with Internet Explorer.

Do While SeDriver.FindElementById("Id").IsDisplayed = False
    DoEvents
Loop

Just replace "IsDisplayed" with "IsPresent", as needed. This method introduces an artificial implicit wait, perfect if what you need is to wait for an element generated by an AJAX request.

-1

Often there are elements on-site that can be immediately found by selenium but cannot be interacted with and usually when we debug at this stage and run the code from there, everything works just fine. The solution I used for that was adding wait.

Sub Pause_for_2_seconds()

    Application.Wait (Now + TimeValue("00:00:02"))

End Sub

And Where ever you feel that the element require some time just add

Call Pause_for_2_seconds 

in your actual Sub

For Example see below

    chr.SendKeys (Keys.Tab)
    Call Pause_for_2_seconds
    
    chr.SendKeys (Keys.Tab)
    
    chr.SendKeys (Date + 52)
    chr.SendKeys (Keys.Tab)
    Call Pause_for_2_seconds
    
    chr.SendKeys (Keys.Tab)
    chr.SendKeys (Keys.Enter)