A Selenium-WebDriver-based browser automation framework implemented for VBA.
Table of Contents
- About The Project
- Requirements
- Getting Started
- Usage
- Element Retrieval
- Timeouts
- Working with iframe
- Working with multiple windows
- Execute JavaScript
- Execute Async JavaScript
- Take Screenshot
- Take Element Screenshot
- Enable Edge IE-mode
- Headless mode
- Customize User-Agent
- Roadmap
- License
- Contribution
- References
The project implements the endpoint node command defined in W3C WebDriver specification through VBA. You can use the project to do browser automation without installing a programming language such as Python, Java, etc. An MS office app and a browser-specific driver are required.
- MS Office(Excel, Word, PowerPoint, etc) 32bit or 64bit
- Browser's driver(Supported Browsers: Firefox, Chrome, Edge and Internet Explorer)
- Download the browser-specific drivers, firefox,chrome,edge, orie.
- In the office, by clicking the Developer tab(if you enabled) or through the shortcut key Alt + F11to open the VBA Editor, and then importWebDriverOptions.cls,WebDriver.cls,WebElement.clsandJsonConverter.basinto your project. (File > Import File)
- Include a reference to "Microsoft Scripting Runtime". (Tools > References Check "Microsoft Scripting Runtime")
- Add browser's driver in the system PATH, or you can also specify the path when launching the corresponding browser's driver.
- Some configurations are required before using iedriver, see here for more details about the configurations.
Sub Example()
    Dim driver As New WebDriver
    driver.Chrome "to/your/path/chromedriver.exe"
    driver.OpenBrowser
    driver.NavigateTo "https://www.python.org/"
    driver.MaximizeWindow
    driver.FindElement(By.ID, "id-search-field").SendKeys "machine learning"
    driver.FindElement(By.ID, "submit").Click
    driver.TakeScreenshot ThisWorkbook.path + "./screenshot.png"
    driver.MinimizeWindow
    driver.CloseBrowser
    
    driver.Quit
    Set driver = Nothing
End Sub    ' Locator Strategies:
    Dim e1, e2, e3, e4, e5, e6, e7, e8 As WebElement
    set e1 = driver.FindElement(By.ID, "id")
    set e2 = driver.FindElement(By.ClassName, "blue")
    set e3 = driver.FindElement(By.Name, "name")
    set e4 = driver.FindElement(By.LinkText, "www.google.com")
    set e5 = driver.FindElement(By.PartialLinkText, "www.googl")
    set e6 = driver.FindElement(By.TagName, "div")
    set e7 = driver.FindElement(By.XPath, "/html/body/div[1]/div[3]")
    set e8 = driver.FindElement(By.CSS, ".search input[type='text']")    Dim elements() As WebElement
    elements = driver.FindElements(By.TagName, "a")
    
    Dim element As Variant
    For Each element In elements
        ' Do your stuff
    Next element    Dim elementRoot As WebElement
    Set elementRoot = driver.FindElement(By.ID, "root1")
    Dim elementChild As WebElement
    Set elementChild = driver.FindElementFromElement(elmentRoot, By.TagName, "div")    Dim elementRoot As WebElement
    Set elementRoot = driver.FindElement(By.ID, "root1")
    Dim elementChildren() As WebElement
    elementChildren() = driver.FindElementsFromElement(elmentRoot, By.TagName, "p")    Dim element as WebElement
    Dim elementShadowRoot As WebElement
    Set elementShadowRoot = driver.FindElement(By.ID, "shadow_id").GetShadowRoot()
    Set element = driver.FindElementFromShadowRoot(eleShadowRoot, By.CSS, "#shadow_css")    Dim elements() As WebElement
    Dim elementShadowRoot As WebElement
    Set elementShadowRoot = driver.FindElement(By.ID, "shadow_id").GetShadowRoot()
    elements() = driver.FindElementsFromShadowRoot(elementShadowRoot, By.CSS, "#shadow_css")    Dim timeoutsDict As Dictionary
    Set timeoutsDict = driver.GetTimeouts()
    Debug.Print timeoutsDict("script")    ' 30000
    Debug.Print timeoutsDict("pageLoad")  ' 300000
    Debug.Print timeoutsDict("implicit")  ' 0    ' Set "script":40000,"pageLoad":500000,"implicit":15000
    driver.SetTimeouts 40000, 500000, 15000- Invoke the function before OpenBrowser.
    Set iframe1 = driver.FindElement(By.ID, "iframe1")
    driver.SwitchToFrame iframe1
    ' Perform some operations...
    driver.SwitchToParentFrame    ' switch back    ' Get current windows's handle.
    Dim hWnd As String
    hWnd = driver.GetWindowHandle
    ' Get the handles of all the windows.
    Dim hWnds As New Collection
    Set hWnds = driver.GetWindowHandles
    ' Switch to another window.
    driver.SwitchToWindow (driver.GetWindowHandles(2))    ' No parameters, no return value.
    driver.ExecuteScript "alert('Hello world!');"
    driver.DismissAlert
    ' Accept parameters, no return value.
    driver.ExecuteScript "alert('Proof: ' + arguments[0] + arguments[1]);", "1+1=", 2
    driver.DismissAlert
    ' Accept parameters, return the result. 
    Dim result As Long
    result = driver.ExecuteScript("let result = arguments[0] + arguments[1];return result;", 1, 2)
    Debug.Print result  ' 3    ' No parameters, no return value.
    driver.ExecuteAsyncScript "alert('Hello world!');"
    driver.WaitUntilAlertIsPresent
    driver.DismissAlert
    ' Accept parameters, no return value.
    driver.ExecuteAsyncScript "alert('Proof: ' + arguments[0] + arguments[1]);", "1+1=", 2
    driver.WaitUntilAlertIsPresent
    driver.DismissAlert
    ' Accept parameters, return the result. 
    Dim result As Long
    result = driver.ExecuteAsyncScript("let result = arguments[0] + arguments[1];return result;", 1, 2)
    Debug.Print result  ' 3    driver.WaitUntilAlertIsPresent
    driver.DismissAlert
    driver.ExecuteScript "prompt('question?')"
    driver.SendAlertText "answer"
    driver.AcceptAlert    ' Take the current webpage screenshot and save it to the specific path.
    driver.TakeScreenshot ThisWorkbook.path + "./1.png"    ' Take the element screenshot directly.
    driver.FindElement(By.ID, "selenium_logo").TakeScreenshot ThisWorkbook.path + "./logo.png"
    ' or
    Dim seleniumLogo As WebElement
    Set seleniumLogo = driver.FindElement(By.ID, "selenium_logo")
    seleniumLogo.TakeScreenshot ThisWorkbook.path + "./logo.png"    Dim driver As New WebDriver
    Dim ieOptions As New WebDriverOptions
    ieOptions.BrowserType = InternetExplorer
    ieOptions.IntroduceFlakinessByIgnoringSecurityDomains = True    ' Optional
    ieOptions.IgnoreZoomSetting = True  ' Optional
    ieOptions.AttachToEdgeChrome = True
    ieOptions.EdgeExecutablePath = "C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
    
    driver.InternetExplorer "C:\WebDriver\IEDriverServer_Win32_4.0.0\IEDriverServer.exe"
    driver.OpenBrowser ieOptions    Dim driver As New WebDriver
    Dim chromeOptions As New WebDriverOptions
    chromeOptions.BrowserType = Chrome
    chromeOptions.ChromeArguments.add "--headless"
    driver.Chrome "C:\WebDriver\chromedriver_win32\chromedriver.exe"
    driver.OpenBrowser chromeOptions    Dim driver As New WebDriver
    Dim firefoxOptions As New WebDriverOptions
    firefoxOptions.BrowserType = Firefox
    firefoxOptions.FirefoxArguments.Add "-headless"
    driver.Firefox "C:\WebDriver\Firefox\geckodriver.exe"
    driver.OpenBrowser firefoxOptions    Dim driver As New WebDriver
    Dim chromeOptions As New WebDriverOptions
    
    driver.Chrome
    chromeOptions.BrowserType = Chrome
    chromeOptions.ChromeArguments.Add "--user-agent=my customized user-agent"
    driver.OpenBrowser chromeOptions
    driver.NavigateTo "https://www.whatismybrowser.com/detect/what-is-my-user-agent/"| Endpoint Node Command | Function Name | Element Function Name | 
|---|---|---|
| New Session | OpenBrowser | |
| Delete Session | CloseBrowser | |
| Status | GetStatus | |
| Get Timeouts | GetTimeouts | |
| Set Timeouts | SetTimeouts | |
| Navigate To | NavigateTo | |
| Get Current URL | GetCurrentURL | |
| Back | Back | |
| Forward | Forward | |
| Refresh | Refresh | |
| Get Title | GetTitle | |
| Get Window Handle | GetWindowHandle | |
| Close Window | CloseWindow | |
| Switch To Window | SwitchToWindow | |
| Get Window Handles | GetWindowHandles | |
| New Window | NewWindow | |
| Switch To Frame | SwitchToFrame | |
| Switch To Parent Frame | SwitchToParentFrame | |
| Get Window Rect | GetWindowRect | |
| Set Window Rect | SetWindowRect | |
| Maximize Window | MaximizeWindow | |
| Minimize Window | MinimizeWindow | |
| Fullscreen Window | FullscreenWindow | |
| Get Active Element | Not yet | |
| Get Element Shadow Root | Not yet | |
| Find Element | FindElement | |
| Find Elements | FindElements | |
| Find Element From Element | FindElementFromElement | FindElement | 
| Find Elements From Element | FindElementsFromElement | FindElements | 
| Find Element From Shadow Root | FindElementFromShadowRoot | |
| Find Elements From Shadow Root | FindElementsFromShadowRoot | |
| Get Element Shadow Root | GetElementShadowRoot | GetShadowRoot | 
| Is Element Selected | Not yet | |
| Get Element Attribute | GetElementAttribute | GetAttribute | 
| Get Element Property | GetElementProperty | GetProperty | 
| Get Element CSS Value | Not yet | |
| Get Element Text | GetElementText | GetText | 
| Get Element Tag Name | Not yet | |
| Get Element Rect | Not yet | |
| Is Element Enabled | Not yet | |
| Get Computed Role | Not yet | |
| Get Computed Label | Not yet | |
| Element Click | ElementClick | Click | 
| Element Clear | ElementClear | Clear | 
| Element Send Keys | ElementSendKeys | SendKeys | 
| Get Page Source | GetPageSource | |
| Execute Script | ExecuteScript | |
| Execute Async Script | ExecuteAsyncScript | |
| Get All Cookies | Not yet | |
| Get Named Cookie | Not yet | |
| Add Cookie | Not yet | |
| Delete Cookie | Not yet | |
| Delete All Cookies | Not yet | |
| Perform Actions | Not yet | |
| Release Actions | Not yet | |
| Dismiss Alert | DismissAlert | |
| Accept Alert | AcceptAlert | |
| Get Alert Text | GetAlertText | |
| Send Alert Text | SendAlertText | |
| Take Screenshot | TakeScreenshot | |
| Take Element Screenshot | TakeElementScreenshot | TakeScreenshot | 
| Print Page | Not yet | 
- Browser Capabilities are not listed above.
- Key action(Such as Enter,Shift,Control) has not been implemented.
Distributed under the MIT License. See LICENSE.txt for more information.
Any suggestions for improvement or contribution to this project are appreciated! Creating an issue or pull request!
- W3C WebDriver Working Draft:
- The Selenium Browser Automation Project
- The W3C WebDriver Spec, A Simplified Guide:
- geckodriver, WebDriver Reference
- Capabilities & ChromeOptions
- Capabilities and EdgeOptions