I've automated downloading of data from a 3rd party website. The process involves logging into the site, downloading the data, then logging out - lather, rinse, repeat for each client.
The code is in VBA using Access as the host and Selenium Basic to handle the browser details. Hate all you want, but I've implemented it as a WebDownloader interface with multiple implementations (one for each of the sites I have to download from). Plus, when the only tool you have is a stone, everything looks like a nail....
Occasionally we can't get logged into the system for one or more of a variety of reasons (like our AP department is very slow about paying bills and a site will shut us off...).
The following code handles the login process. Prior to this, the browser is opened and the website's login page is retrieved. Once I've gotten to this point, it's safe to assume that everything is ready for the login process to begin.
This works, but it's ugly, and my concern is that the normal, expected course of action goes through the error handler.
Private Sub IWebDownloader_LoginToWebPage()
Const USER_NAME_FIELD_ID As String = "login"
Const PASSWORD_FIELD_ID As String = "password"
Const LOGIN_BUTTON_CLASS_ID As String = "btn-form"
LogManager.Log TraceLevel, "ApptPlusWebDownloader.IWebDownloader_LoginWebPage"
On Error GoTo ErrorHandler
With this.Driver
.FindElementById(USER_NAME_FIELD_ID).SendKeys this.UserID
.FindElementById(PASSWORD_FIELD_ID).SendKeys this.Password
.FindElementByClass(LOGIN_BUTTON_CLASS_ID).Click
End With
Dim noteElement As WebElement
Set noteElement = this.Driver.FindElementByClass("note")
'assumes we find a note which, normally, we shouldn't
this.IsLoggedIn = False
If InStr(1, noteElement.text, "disabled") Then
LogManager.Log WarnLevel, "Login disabled --- ApptPlus message: " & noteElement.text
Else
LogManager.Log WarnLevel, "Login warning --- ApptPlus message: " & noteElement.text
End If
CleanExit:
Exit Sub
ErrorHandler:
With Err
If .Number = 7 Then
this.IsLoggedIn = True
Else
LogManager.Log ErrorLevel, "ApptPlus Failed to login. UserID: " & this.UserID
this.IsLoggedIn = False
End If
End With
Resume CleanExit
End Sub
The only way to determine if there's a login issue is to look for the note element appearing on the login page - failure to find that element is expected, preferred and is a good thing.
I could resolve this by wrapping with an OERN like this:
On Error Resume Next
Set noteElement = this.Driver.FindElementByClass("note")
'handle the expected error which is really a good thing here
On Error GoTo ErrorHandler
Is that the best way to go about this, or does someone see something better I could do?
I'm also open to any other tips or suggestions anyone sees that could improve the code.