Using SeleniumBasic v3.141.0.0 with AHK

Helpful script writing tricks and HowTo's
burque505
Posts: 1447
Joined: 22 Jan 2017, 19:37

Using SeleniumBasic v3.141.0.0 with AHK

20 Feb 2021, 14:16

How to install SeleniumBasic 3.141.0.0 and register the DLLs

Update: February 21, 2021. Added basic Actions tutorial below.

SeleniumBasic 3.141.0.0 is a rewrite of florentbr's SeleniumBasic to make it more current.

Although arguably inferior to GeeKDude's Chrome.AHK, v3 can automate Chrome, Edge, Firefox, IE, Opera and Safari out-of-the-box, so it may be better choice for some projects.

It was coded by prolific Chinese author ryueifu. Although clearly directed toward VBA (as was florentbr's version) we can use it to good effect in AutoHotkey. Also, both versions can coexist, as for V3 we use "ComObjCreate("SeleniumBasic.*"). Unlike v2, we frequently need to create more than one COM object for our scripts. The main objects you'll need to create are "SeleniumBasic.IWebDriver", "SeleniumBasic.ChromeDriverService" (adapt as needed for different browsers), "SeleniumBasic.ChromeOptions" (only for Chrome, obviously), "SeleniumBasic.Screenshot", "SeleniumBasic.Keys" (critical if you want to send modifier keys, etc.), and, possibly, "SeleniumBasic.Utility".

You can download it from https://files.cnblogs.com/files/ryueifu-VBA/SeleniumBasic.zip.
You'll want to virus-check it, of course! Unblock the zip archive before opening.
Inside the zip are these files:

SeleniumBasic.dll
SeleniumBasic.tlb
(These two provide objects and members in the SeleniumBasic namespace.)
RegAsm.bat
(Run it as admin from the directory where you extracted the DLLs)
UnRegAsm.bat
(Unregister SeleniumBasic, likewise as admin)
WebDriver.dll
WebDriver.Support.dll:
(V3 also relies on these two libraries, so keep all these files together)

Save all these files to a location on your system where you won't have to move them. As you'll be registering DLLs based on this location, you may break your v3 scripts if you move them.
Run RegAsm.bat as admin from the directory where the DLLs are (and hopefully will stay), refresh your environment, and you should be good to go.

Using various webdrivers

v3 scripts will require you to supply the location of both your browser executables and the location of e.g. chromedriver.exe, msedgedriver.exe, and geckodriver.exe. I've added that location (for me, C:\Downloads\Webdrivers) to my PATH, which has cut down on the number of webdrivers littering my system.

My Regasm.bat looks like this:

Code: Select all

@ECHO OFF
cd /d %~dp0
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /codebase "SeleniumBasic.dll" /tlb "SeleniumBasic.tlb"
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" /codebase "SeleniumBasic.dll" /tlb "SeleniumBasic.tlb"
PAUSE
CLS
My UnRegAsm.bat looks like this:

Code: Select all

@ECHO OFF
cd /d %~dp0
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /u "SeleniumBasic.dll" /tlb "SeleniumBasic.tlb"
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" /u "SeleniumBasic.dll" /tlb "SeleniumBasic.tlb"
PAUSE
CLS
CAVEAT: I personally haven't been able to get "Actions" methods, used in SeleniumBasic to automate the mouse and keyboard, to work in either version for AutoHotkey. (I suspect this is because AHK is co-opting the mouse and keyboard, but it's just as likely that I just don't really know what I'm doing.) @Xtra's help below got me started with Actions.

DOCUMENTATION:
None yet, unfortunately. I'm in the process of translating some of the VBA-related blog posts from Mandarin, but it's hard slogging. You can go to these blog posts and try your hand at some machine translation if you want to get farther than the simple code provided gets you.

Also, use dnspy for this and all your other dotnet disassembly/inspection needs! It's certainly been helpful for me.

TESTING V3:

As @Joe Glines of the-automator.com was kind enough to provide us with lots of examples for SeleniumBasic 2, I though I'd try to automate his page in a way analogous to his first example. The code below is a work in progress, so please be gentle! If v3 is correctly installed on your system you should be able to just sit back and watch. You'll need Chrome installed at the location shown in the code for this to work.

Code: Select all

SetBatchLines, -1

wd := ComObjCreate("SeleniumBasic.IWebDriver")
svc := ComObjCreate("SeleniumBasic.ChromeDriverService")
options := ComObjCreate("SeleniumBasic.ChromeOptions")
scr := ComObjCreate("SeleniumBasic.Screenshot")
;ele := ComObjCreate("SeleniumBasic.IWebElement")
U := ComObjCreate("SeleniumBasic.Utility")
Keys := ComObjCreate("SeleniumBasic.Keys") ; NEEDED!!!!
;actions := ComObjCreate("SeleniumBasic.Actions")

;initialize - adapt to suit your system
svc.CreateDefaultService.driverPath := "C:\Downloads\WebDrivers"
;;;;;;;;
options.BinaryLocation := "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
options.AddExcludedArgument("enable-automation")
options.AddArgument("--start-maximized")
;;;;;
svc.HideCommandPromptWindow := True

;start browser service
wd.New_ChromeDriver(svc, options)

wd.URL := ("https://the-automator.com/")
msgbox , , Automating The-Automator,We use SeleniumBasic 3.141.00`nto automate Joe Glines's famous page.`nFirst `, his "hello world" example, 3

wd.FindElementByName("s").SendKeys("hello world")
wd.FindElementByName("s").SendKeys(Keys.ENTER) ;http://seleniumhome.blogspot.com/2013/07/how-to-press-keyboard-in-selenium.html 

/* use to make sure document is loaded
loop {
	ready := wd.ExecuteScript("return document.readyState")
	if (ready := "complete")
		break
	else
		sleep, 1000
}
*/



wd.ExecuteScript("arguments[0].setAttribute('value', 'hello world')", wd.FindElementByName("s")) 

repl_text := "Automate Now!"

;;;;;;;;;;;;;;;;;;;;
; see e.g. https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate
;;;;;;;;;;;;;;;;;;;;
js =
(
var cats2monkeys = document.evaluate(".//h3[normalize-space()='Categories']", document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
cats2monkeys.innerText = " %repl_text% "
)
msgbox, ,Categories automation,We show various ways to automate the 'Select Categories' dropdown box.,4
sleep 1000
msgbox , ,Selecting dropdown options by CSS, We can use CSS to query`, locate and select dropdown options.`nA couple of examples follow.`nSee the code., 4
;~ myele := wd.ExecuteScript("return document.querySelector(""#cat > option:nth-child(8)"").innerText")
;~ msgbox, ,Option by CSS, %myele%, 2
myele := wd.ExecuteScript("return document.querySelector(""#cat > option[value*='1323']"").innerText")
msgbox, ,Option by CSS, We locate option with value '1323' and get its 'innerText':`n"%myele%", 3
myele := wd.ExecuteScript("return document.querySelector(""#cat > option[value*='1008']"").innerText")
msgbox, ,Option by CSS, We locate option with value '1008' and get its 'innerText':`n"%myele%", 3

;~ wd.ExecuteScript(js)
;~ U.Sleep(2000)
;~ wd.FindElementByName("cat").click()
;~ U.Sleep(1000)

num9 := wd.findElementById("cat") ;
;;;Take a screenshot of an element!
pic9 := num9.GetScreenShot
pic9.SaveAsFile(A_ScriptDir . "\cats.png", 0) ; 0 is png
/* via dnspy
Utility.ScreenshotImageFormat Bmp = 4;
Utility.ScreenshotImageFormat Gif = 2;
Utility.ScreenshotImageFormat Jpeg = 1;
Utility.ScreenshotImageFormat Png = 0;
Utility.ScreenshotImageFormat Tiff = 3;
*/
;msgbox, , ,%repl_text%, 2
;;;;;;;;;;;;;;;;;;;;
; see e.g. https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate
;;;;;;;;;;;;;;;;;;;;
botzJs = 
(
return document.evaluate(".//h3[normalize-space()='%repl_text%']", document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
)
;msgbox %botzJs%
botz := wd.ExecuteScript(botzJs)

bot := botz.GetScreenShot
bot.SaveAsFile(A_ScriptDir . "\automate.png", 0)
;;;
msgbox ,  ,Select Option by Index, We now get the option index from the HTML`nand use that to select.`nWe select option index 9 - Automate by Task`nSee the code.,2
wd.findElementByCssSelector("#cat[class='postform']").SelectByIndex(9) ; Go to an option
;;;;;;;;;;;;;;;;;;;;
msgbox, ,Content of dropdown, % wd.findElementByCssSelector("#cat[class='postform']").SelectedOption.text , 2
;;;;;;;;;;;;;;;;;;;;

;wd.Manage.Window.FullScreen ; As you have guessed, fullscreen

;;;;;;;;;;;;;;;;;;
;;; If you know the text of the option, you can select it like this:
;;; Here we'll click AHK Studio
;;;;;;;;;;;;;;;;;;

msgbox , ,Select Option by Text, If you know the text of the option`nyou can select it.`nWe look for AHK Studio.`nSee the code, 2
cat := wd.ExecuteScript("return document.querySelector(""#cat"")")
cat.Click
cat.SelectByText("AHK Studio", True)

sleep 2000
;;;;;;;;;;;
; Open context menu
msgbox , ,Open DevTools, We can open DevTools`nby sending right click - n , 3
sleep, 2000
MouseClick, Right
Send, n
;~ body := wd.ExecuteScript("return document.body")
;~ act := actions.Create(wd)
;~ act.ContextClick(body)
sleep 3000
;;;;;;;;;;;
msgbox , , Take screenshot of element, We can take screenshots of individual elements!`nLook in the script directory`nfor 'cats.png' and 'automate.png'`nwhen the demo ends., 4
sleep, 1000

msgbox, ,Exiting, End of demo `nThanks for watching`!, 2
wd.Quit()
wd := svc := options := scr := ele := actions := U := ""

ExitApp
Please share your comments and experiences.
Regards,
burque505
Last edited by burque505 on 21 Feb 2021, 11:57, edited 3 times in total.
User avatar
Xtra
Posts: 2062
Joined: 02 Oct 2015, 12:15

Re: Using SeleniumBasic v3.141.0.0 with AHK

20 Feb 2021, 17:26

Thanks for posting this.

Ive used actions before to offset click an element.
Example:

Code: Select all

driver.Actions.moveToElement(element).moveByOffset(-100, 0).click().perform()
I will eventually try this version. Wish it had its own installer to keep it simple and user friendly.
burque505
Posts: 1447
Joined: 22 Jan 2017, 19:37

Re: Using SeleniumBasic v3.141.0.0 with AHK

20 Feb 2021, 17:56

@Xtra, I really appreciate the tip for Actions. I will try it in both versions and report back.
EDIT: No luck with v2 or v3. Would you be able to post a short AHK script with Actions working, either v2 or v3 of Selenium? Thanks in advance!
Regards,
burque505
burque505
Posts: 1447
Joined: 22 Jan 2017, 19:37

Re: Using SeleniumBasic v3.141.0.0 with AHK

20 Feb 2021, 18:43

@Xtra, I have had a little success with Actions so far now in v3. Here is the code:
Spoiler
The syntax is not intuitive to me. The lines

Code: Select all

wd.New_ChromeDriver(svc, options)
wd.URL := "https://www.startpage.com"
Actions.Create(wd)
apparently mean "Create a new driver 'wd'; send it to a URL; then create Actions capabilities for this existing driver 'wd' ". Then I can perform

Code: Select all

button := wd.FindElementById("hamburger-button")
Actions.MoveToElement(button).click().perform()
That's all the farther I've gotten, but your input certainly encouraged me to get there. Thanks! I will follow up with more on actions as I have more success.
Regards,
burque505
Last edited by burque505 on 20 Feb 2021, 18:50, edited 1 time in total.
User avatar
Xtra
Posts: 2062
Joined: 02 Oct 2015, 12:15

Re: Using SeleniumBasic v3.141.0.0 with AHK

20 Feb 2021, 18:44

I removed the offset click to simplify the example:

Code: Select all

#NoEnv

driver := ComObjCreate("Selenium.ChromeDriver") 
driver.Get("https://www.Google.com")
element := driver.FindElementByXPath("//input[@class='gLFyf gsfi']")
driver.Actions.moveToElement(element).click().perform()
MsgBox, 4096, Actions, ??, 5
driver.quit()
ExitApp
User avatar
Xtra
Posts: 2062
Joined: 02 Oct 2015, 12:15

Re: Using SeleniumBasic v3.141.0.0 with AHK

20 Feb 2021, 18:48

For V3 if there was documentation (in english) it would be easier to deal with.
Thanks again for posting.
burque505
Posts: 1447
Joined: 22 Jan 2017, 19:37

Re: Using SeleniumBasic v3.141.0.0 with AHK

20 Feb 2021, 18:53

@Xtra, thanks to you too. Your example works great in v2. The attached doesn't really qualify as 'documentation' since it's 1) all machine-translated and 2) meant for VBA, but maybe it'll help for now.
Attachments
docs-v3.zip
(53.53 KiB) Downloaded 10 times
burque505
Posts: 1447
Joined: 22 Jan 2017, 19:37

Re: Using SeleniumBasic v3.141.0.0 with AHK

21 Feb 2021, 11:52

Use a behavior chain to simulate mouse and keyboard operations.

The Actions class in SeleniumBasic can implement mouse and keyboard operations. Actions can be chained.
These are the available Actions.

Code: Select all

Build() - void
Click(IWebElement) *
ClickAndHold(IWebElement) *
ContextClick(IWebElement) *
ConvertKey(string)
Create(IWebDriver)
DoubleClick(IWebElement) *
DragAndDrop(IWebElement, IWebElement)
DragAndDropToOffset(IWebElement, int, int)
KeyDown(string, IWebElement) *
KeyUp(string, IWebElement) *
MoveByOffset(int, int)
MoveToElement(IWebElement, int, int) ** last two indicate an offset - omit if none.
Perform() - void
Release_(IWebElement)
Sendkeys(string, IWebElement) *

The Perform method must be the last command in chain, and is not optional.
Some IWebElement parameters are OPTIONAL. Those with one or more optional parameters are marked with an asterisk above.

The code in the first spoiler below uses Actions to fill in the StartPage search box, select all text in it, cut the text to the clipboard, and shows the clipboard content in a MsgBox.
These lines are related to our Actions:

Code: Select all

Actions.Create(wd) ; This syntax is very confusing for me. I read it to mean "Driver 'wd' can hereafter create Actions."
; ...
Actions.KeyDown(Keys.Control, search).SendKeys("a", search).KeyUp(Keys.Control,search).KeyDown(Keys.Control,search).SendKeys("x",search).KeyUp(Keys.Control,search).Perform
Spoiler

This script visits StartPage, searches for "Selenium", then clicks the hamburger menu in the upper right corner.
The lines related to our Actions are

Code: Select all

Actions.Create(wd) ; Always need to do this after the browser 'wd' as created, and preferably after a URL is visited.
; . . .
; After searching for 'Selenium', click the hamburger-menu button.
button := wd.FindElementById("hamburger-button") 
Actions.MoveToElement(button).click().perform()
EDIT: N.B.:
'Build()' is likely not necessary or even usable for us in AHK. This SO post mentions that 'Perform()' now incorporates 'Build()' in Selenium, that 'build' is included in 'perform' in the Java binding, and that Ruby and Python don't even have 'build()'.
Here's a code snippet (not a standalone script) demonstrating how you might create an Action chain and then use or re-use it as required.
If you like, for testing you can substitute it into the script in the spoiler below.

Code: Select all

Actions.Create(wd)
search := wd.FindElementById("q")
search.SendKeys("Selenium")
search.SendKeys(Keys.ENTER)
U.Sleep(1000)

button := wd.FindElementById("hamburger-button")
builder := Actions.MoveToElement(button).click() ; create the Action chain (here a chain with just one 'link');
builder.Perform ; now use (or perhaps later re-use) the Action chain.
Spoiler
Note that the parameters following KeyDown and KeyUp need to be obtained from the Keys class. The supported keys are in the spoiler below.
Spoiler
All comments and suggestions appreciated - I'm basically just documenting my own learning process with SeleniumBasic, and I'm not very far along yet. Selenium is a deep topic.

Regards,
burque505

Return to “Tutorials”

Who is online

Users browsing this forum: No registered users and 7 guests