[Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No IE!

Post your working scripts, libraries and tools for AHK v1.1 and older
Gh0sTG0
Posts: 55
Joined: 25 Jun 2018, 07:58

Re: [Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No IE!

19 Jul 2023, 12:39

Hi. Is there some way to get list of tabs in order as they are from left to right in my chrome?
ars4l4n
Posts: 15
Joined: 26 Aug 2020, 07:27

Re: [Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No Selenium!

11 Sep 2023, 12:31

burque505 wrote:
13 Sep 2020, 07:57
Hi, @ars4l4n,

Code: Select all

document.querySelector("#twotabsearchtextbox")click();
runs without error for me too, but there's no event listener yet. Try this:

Code: Select all

inputbox = document.querySelector("#twotabsearchtextbox");
inputbox.addEventListener('click', function (event) {
  alert('Element clicked through function!');
});
Then run this in the console:

Code: Select all

inputbox.click();
You should get the alert as shown.
After that it's just a matter of figuring out what real stuff you want the event listener to actually do! :D
(I'll try here in a bit to see if I can get the cursor to blink inside the input field, if that's the general idea.)

EDIT: This code works for me now to get the cursor blinking in the search field so you can just start typing. (It drove me nuts for half an hour, because Google was "offering" to translate the page to English for me. :problem: When I finally clicked on the settings for that popup and told Google to NEVER translate the page it worked fine.)

Code: Select all

#Include Chrome.ahk
ChromeInst := new Chrome("ChromeProfile")
PageInstance := ChromeInst.GetPage()
PageInstance.Call("Page.navigate", {"url": "https://www.amazon.de/"})
PageInstance.WaitForLoad()
Send, {Tab} ; Needed to get focus away from address bar for me;
Sleep, 1000
PageInstance.Evaluate("searchfield = document.querySelector(""#twotabsearchtextbox"");")
PageInstance.Evaluate("searchfield.focus();")
PageInstance.Evaluate("searchfield.select();")
Sleep, 10000
PageInstance.Call("Browser.close")
ExitApp
Regards,
burque505
nice, it worked
sry for the late reply
ars4l4n
Posts: 15
Joined: 26 Aug 2020, 07:27

Re: [Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No IE!

11 Sep 2023, 15:03

I'm using this script to select the youtube searchfield but it sometimes gives me an error which I don't understand because I'm running an almost identical script for other websites and they don't have any issues either.
Screenshot of the Error

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#Include Chrome.ahk
SetTitleMatchMode, 2


WinWaitActive YouTube
PageInstance := Chrome.GetPageByURL("youtube", "contains")
PageInstance.WaitForLoad()
Sleep, 1000
PageInstance.Evaluate("searchfield = document.querySelector(""#search.ytd-searchbox"");")
PageInstance.Evaluate("searchfield.focus();")
PageInstance.Evaluate("searchfield.select();")
Sleep, 300
Send, {Esc}
Sleep, 500
Run, YouTube Suchfeld fokussieren 2.ahk
ExitApp
Any idea what's going on?
ocnuybear
Posts: 8
Joined: 15 Jul 2018, 12:52

Re: [Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No IE!

09 Jan 2024, 04:44

Does Chrome.ahk library work with AHK v2?
gregster
Posts: 9080
Joined: 30 Sep 2013, 06:48

Re: [Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No IE!

09 Jan 2024, 06:27

ocnuybear wrote:
09 Jan 2024, 04:44
Does Chrome.ahk library work with AHK v2?
No, not the original one. There is a v2 version by our forum member thqby, though: https://github.com/thqby/ahk2_lib/blob/master/Chrome.ahk
I haven't tried it yet.
c4p
Posts: 21
Joined: 18 Jan 2017, 18:38

Re: [Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No IE!

14 Jan 2024, 14:49

I think I have found a bug in Chrome.ahk. When instantiating Chrome with url included, WaitForLoad() Method does not work. Using the code example from the 1st page, things work as expected.

Code: Select all

#Include Chrome.ahk

; Create an instance of the Chrome class using
; the folder ChromeProfile to store the user profile
FileCreateDir, ChromeProfile
ChromeInst := new Chrome("ChromeProfile")

; Connect to the newly opened tab and navigate to another website
; Note: If your first action is to navigate away, it may be just as
; effective to provide the target URL when instantiating the Chrome class
PageInstance := ChromeInst.GetPage()
PageInstance.Call("Page.navigate", {"url": "https://autohotkey.com/"})
PageInstance.WaitForLoad()

; Execute some JavaScript
PageInstance.Evaluate("alert('Hello World!');")

; Close the browser (note: this closes *all* pages/tabs)
PageInstance.Call("Browser.close")
PageInstance.Disconnect()

ExitApp
return
Now lets change it as suggested in the comment "...it may be just as effective to provide the target URL when instantiating the Chrome class"

Code: Select all

#Include Chrome.ahk
FileCreateDir, ChromeProfile
ChromeInst := new Chrome("ChromeProfile", "https://autohotkey.com/") ; this line changed
PageInstance := ChromeInst.GetPage()
; PageInstance.Call("Page.navigate", {"url": "https://autohotkey.com/"}) ; this line removed
PageInstance.WaitForLoad()
PageInstance.Evaluate("alert('Hello World!');")
PageInstance.Call("Browser.close")
PageInstance.Disconnect()

ExitApp
return
The alert fires before the page is fully loaded and causes a subsequent error. Here is a workaround.

Code: Select all

#Include Chrome.ahk
url := "https://autohotkey.com/"
ChromeInst := new Chrome("ChromeProfile", url) ; new instance
PageInstance := ChromeInst.GetPage()
PageInstance.Call("Page.navigate", {"url": url}) ; must renavigate to make WaitForLoad() work
PageInstance.WaitForLoad()
PageInstance.Evaluate("alert('Hello World!');")
PageInstance.Call("Browser.close")
PageInstance.Disconnect()
ExitApp
return
Dixtroy
Posts: 12
Joined: 05 Jul 2019, 03:40

Re: [Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No IE!

22 Jan 2024, 09:27

If we want to use the same script on several pages, it speeds up the process significantly if we don't send the javascript again and again using Evaluate(), but record it in DevTool and send only the ID. I suggest for you, to add these functions to the class:

Code: Select all

/*
			Enable script compilation. For example:
			
			PageInst.EnableScript( )
      ;Channel response: {"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"origin":"","name":"PopEngineContextName"}}}
      ;Channel response: {"id":5,"result":{}}
		*/		
		EnableScript()
		{
      if !this.Connected
				throw Exception("Not connected to tab")
			
			; Use a temporary variable for ID in case more calls are made
			; before we receive a response.
			ID := this.ID += 1
			this.ws.Send(Chrome.JSON.Dump({"id": ID
			, "method": "Runtime.enable"}))
			
			if !WaitForResponse
				return
			
			; Wait for the response
			this.responses[ID] := False
			while !this.responses[ID]
				Sleep, 50
			
			; Get the response, check if it's an error
			response := this.responses.Delete(ID)
			if (response.error)
				throw Exception("Chrome indicated error in response", -1, Chrome.JSON.Dump(response.error))
			
			return response 

		}		

		/*
			Compiles JavaScript expression, return scriptId. For example:
			
			PageInst.EnableScript( )
			PageInst.CompileScript("alert(""I can't believe it's not IE!"");") ;
      ;Channel response: {"id":5,"scriptId":76}
		*/		
		CompileScript(JS)
		{
			response := this.Call("Runtime.compileScript",
			( LTrim Join
			{
				"expression": JS,
				"sourceURL": "",
				"persistScript": Chrome.JSON.True
			}
			))
			
			if (response.exceptionDetails)
				throw Exception(response.result.description, -1
			, Chrome.JSON.Dump({"Code": JS
			, "exceptionDetails": response.exceptionDetails}))
			
			return response.scriptId
		}		

		/*
			Run compiled JavaScript by its scriptId. For example:
			
			PageInst.EnableScript( )
			si:=PageInst.CompileScript("JSON.stringify({""return"":1},0,0)");
      ;Channel response: {"id":6,"scriptId":77}
			va:=PageInst.RunScript( si ) ;
      ;Channel response: {"return":1}
		*/		
		RunScript(scriptId)
		{
			response := this.Call("Runtime.runScript",
			( LTrim Join
			{
				"scriptId": scriptId,
				"objectGroup": "console",
				"includeCommandLineAPI": Chrome.JSON.True,
				"silent": Chrome.JSON.False,
				"returnByValue": Chrome.JSON.False,
				"awaitPromise": Chrome.JSON.False
			}
			))
			
			if (response.exceptionDetails)
				throw Exception(response.result.description, -1
			, Chrome.JSON.Dump({"scriptId": scriptId
			, "exceptionDetails": response.exceptionDetails}))
			
			return response.result
		}
An example:

Code: Select all

#Include <Chrome>
#Include <JSON>

Br := new Chrome("ChromeProfile"
								,""
								,"--remote-debugging-port=9222"
								,"C:\Program Files\Google\Chrome\Application\chrome.exe"
								,9222)
Sleep, 1000 ;TODO: wait for window
Pa := Br.GetPage(1)
Pa.Call("Page.navigate", {"url": "https://www.google.com/search?q=chrome+devtools+websocket&oq=chrome+devtools+websocket"} )
js1:= "try{"
			. " function gi( xpath ) { var item=document.evaluate( xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue; return item;}"
		  . " var ret={}; "
			. " ret['Button']=gi('//div[@jsname=\'bVqjv\']').innerHTML;"
			. "	JSON.stringify(ret,0,0);" 
			. "}"
			. "catch( e ){"
			;. "  console.log( e );"
			. "}" 
js2:= "try{"
			. " function gi( xpath ) { var item=document.evaluate( xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue; return item;}"
		  . " var ret={}; "
			. " ret['Keresomezo']=gi('//textarea[@jsname=\'yZiJbe\']').innerHTML;"
			. "	JSON.stringify(ret,0,0);" 
			. "}"
			. "catch( e ){"
			;. "  console.log( e );"
			. "}" 
						
;msgbox % js
Sleep, 3000 ;TODO: wait for window
;ret:=Pa.Evaluate( js1 )

ret:=Pa.enableScript( )
msgbox % ret
scid1:=Pa.compileScript( js1 )
msgbox % scid1
scid2:=Pa.compileScript( js2 )
msgbox % scid2
;msgbox % scid, "object")
scr:=Pa.runScript( scid1 )
msgbox % scr

scr:=Pa.runScript( scid2 )
msgbox % scr
inseption86
Posts: 206
Joined: 19 Apr 2018, 00:24

Re: [Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No IE!

24 Feb 2024, 10:47

Good afternoon I have several active windows users who have chrome running in developer mode. But I receive a link not from my active chrome, but from another user's active chrome. Is it possible to fix this somehow?

Code: Select all

if (Chromes := Chrome.FindInstances()) {
	ChromeInst := {"base": Chrome, "DebugPort": Chromes.MinIndex()}	
	winwait, ahk_exe chrome.exe
}
else {
  Clipboard := "--remote-debugging-port=9222"
  ChromeInst.Kill()
  ExitApp
}

; --- Connect to the page ---
if !(Page := ChromeInst.GetPage( , , fnCallBack))
{
	MsgBox, Could not retrieve page!
	ChromeInst.Kill()
	ExitApp
}
else
   Page.WaitForLoad()


url :=  Page.Evaluate("window.location.href;").Value

MsgBox % url 
ChromeInst.Kill()
ExitApp


Is it possible to fix this?

Code: Select all

FindInstances()
	{
		static Needle := "--remote-debugging-port=(\d+)"
		Out := {}
		for Item in ComObjGet("winmgmts:")
			.ExecQuery("SELECT CommandLine FROM Win32_Process"
			. " WHERE Name = 'chrome.exe' AND USERNAME = '" A_userName "'")
				;~ if Instr(Item.CommandLine, "smirnovaa")
					;~ Out := 9222
					;~ MsgBox % Item.CommandLine
					if RegExMatch(Item.CommandLine, Needle, Match)
					{
						Out[Match1] := Item.CommandLine
					}
			
		return Out.MaxIndex() ? Out : False
	}

User avatar
Xtra
Posts: 2750
Joined: 02 Oct 2015, 12:15

Re: [Library] Chrome.ahk - Automate Google Chrome using native AutoHotkey. No IE!

24 Feb 2024, 15:25

inseption86 wrote:
24 Feb 2024, 10:47
Good afternoon I have several active windows users who have chrome running in developer mode. But I receive a link not from my active chrome, but from another user's active chrome. Is it possible to fix this somehow?
Sounds like a conflict of using the same debugging port number.

Example: If all users are on a Terminal Server they will need to set unique port numbers.

Code: Select all

; user 1
--remote-debugging-port=9222

; user 2
--remote-debugging-port=9223

; user 3
--remote-debugging-port=9224

; user 4
--remote-debugging-port=9225
HTH

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: alnz123 and 56 guests