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 + F11
to open the VBA Editor, and then importWebDriverOptions.cls
,WebDriver.cls
,WebElement.cls
andJsonConverter.bas
into 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