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

Post your working scripts, libraries and tools for AHK v1.1 and older
jdpmdphd
Posts: 13
Joined: 03 Jul 2015, 13:33

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

09 Mar 2021, 17:22

In chrome.ahk. both Jxon_True() and Jxon_False() return an empty static structure. WHY??

PROBLEM:
result from Evaluate has EMPTY fields, even though paste of same code into console reports the correct values.

Code: Select all

result:=Page.evaluate(...)
calls the jsx in the context of the console access associated web page. BUT, return values are empty... for example, I can click a button with Page.Evaluate(click . "on('Continue')")
where Continue is a button innerHTML and

Code: Select all

click=
(
function on(text){
var selector='button';
var elements=document.querySelectorAll(selector);
var matched=Array.prototype.filter.call(elements, function(element){
  return RegEx(text).test(element.textContent);
});
var lastMatch=matches[matches.length-1];
if (lastMatch){
   lastMatch.click();
   return true;
} else return false;
}
)
[Mod edit: [code][/code] tags added.]

BUT, result object has EMPTY fields, so I cannot use the result for workflow logic
gregster
Posts: 8921
Joined: 30 Sep 2013, 06:48

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

09 Mar 2021, 17:29

jdpmdphd wrote:
09 Mar 2021, 17:22
PROBLEM:
result from Evaluate has EMPTY fields, even though paste of same code into console reports the correct values.

Code: Select all

result:=Page.evaluate(...)
calls the jsx in the context of the console access associated web page. BUT, return values are empty...
Afaik, Evaluate() returns an object with different properties. Try

Code: Select all

result:=Page.evaluate(...).value
that's a different value property than in the DOM - here, it's part of Google's chrome debugging protocol - at least, that will work to get DOM elements like value, innerText, outerHTML... - but not sure if it will work with a function return value; perhaps you have to write something to the console, and then read from there instead.


Re the boolean values/objects: Afaik, they actually get handled in the Jxon_Dump() method (excerpt below, see Chrome.ahk source for full code):

Code: Select all

	Jxon_Dump(obj, indent:="", lvl:=1)
	{
		static q := Chr(34)
		
		if IsObject(obj)
		{
			; [...]
			
			prefix := SubStr(A_ThisFunc, 1, InStr(A_ThisFunc, ".",, 0))
			fn_t := prefix "Jxon_True",  obj_t := this ? %fn_t%(this) : %fn_t%()
			fn_f := prefix "Jxon_False", obj_f := this ? %fn_f%(this) : %fn_f%()
			
			if (&obj == &obj_t)
				return "true"
			else if (&obj == &obj_f)
				return "false"
;[...]
btw, there is also teadrinker's Chrome.ahk variant that uses a different JSON approach: see https://www.autohotkey.com/boards/viewtopic.php?f=6&t=42890&start=360#p382756
jdpmdphd
Posts: 13
Joined: 03 Jul 2015, 13:33

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

10 Mar 2021, 00:06

The teadrinker version of Chrome.ahk solved the result.value (was empty, now has -1 for true, 0 for false).

Page.WaitForLoad() still fails - documentation says that just looking for document.readyState = "complete" is INSUFFICIENT - it only shows ready to load, so for react code web page, it says readyState="complete" too early.

Code: Select all

while this.Evaluate("document.readyState").value != DesiredState
				Sleep, Interval
document.readyState gets set when the DOM is constructed, e.g. all elements are attached to document, but not necessarily all content.

window.onload fires later, when script files, images, CSS files, etc. are all loaded.

Thus WaitForLoad() should inject a variable setter into document.onLoad, then wait for that signal. This could over-ride document.readyState with new

e.g.

Code: Select all

WaitForLoad(DesiredState:="FullyLoaded", Interval:=100)
{
notifier=
(
     document.head.setAttribute('status','NotLoaded') ;
     window.onload = function ( ) { document.head.setAttribute('status','FullyLoaded');  } ;
)
			this.Evaluate(notifier)
			
			while ((this.Evaluate("document.head.getAttribute('status')").value) != DesiredState)
				Sleep, Interval
}
[Mod edit: [code][/code] tags added.]
User avatar
Xeo786
Posts: 759
Joined: 09 Nov 2015, 02:43
Location: Karachi, Pakistan

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

10 Mar 2021, 03:18

I have never face page loading issue with readystate except pages with iframes https://www.w3schools.com/tags/tag_iframe.asp and then I found solution too

Some web pages only reload/update specific documents inside iframes and Javascript context is set to one default frame

You can check readystate of specific Iframe using its ID, i.e. try following code inside chrome console while specific iframe loading

Code: Select all

$('#frameid').contentDocument.readyState
"When there is no gravity, there is absolute vacuum and light travel with no time" -Game changer theory
Ambro53
Posts: 1
Joined: 14 Mar 2021, 11:03

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

14 Mar 2021, 11:25

jdpmdphd wrote:
10 Mar 2021, 00:06
The teadrinker version of Chrome.ahk solved the result.value (was empty, now has -1 for true, 0 for false).
I had the same issue with boolean values (using Edge Chromium), but teadrinkers version is not working for me at all.
After trying and failing to figure out what this was/wasn't doing and trying to fix it:
gregster wrote:
09 Mar 2021, 17:29
Re the boolean values/objects: Afaik, they actually get handled in the Jxon_Dump() method (excerpt below, see Chrome.ahk source for full code):

Code: Select all

Jxon_Dump(obj, indent:="", lvl:=1)
	{
		static q := Chr(34)
		
		if IsObject(obj)
		{
			; [...]
			
			prefix := SubStr(A_ThisFunc, 1, InStr(A_ThisFunc, ".",, 0))
			fn_t := prefix "Jxon_True",  obj_t := this ? %fn_t%(this) : %fn_t%()
			fn_f := prefix "Jxon_False", obj_f := this ? %fn_f%(this) : %fn_f%()
			
			if (&obj == &obj_t)
				return "true"
			else if (&obj == &obj_f)
				return "false"
;[...]
I went for a dirty but simple option:

Code: Select all

JS=
(
	document.body.contains(document.getElementById('theThingImtryingToFind')) ? 'true' : 'false';
)
result := Page.Evaluate(JS).value
if result=="true"
	msgbox Found it.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

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

17 Mar 2021, 06:24

Does anybody know a way to handle "Messages from webpage"?
I want to know when they pop up, what text they are displaying, and press a specific button.

Currently I just do a "Blind" Sendinput,{enter}, I was wondering if there is a better way through Selenium/controls.

Unfortunately, the two websites where I get these pop ups (and want to control them), are not public accessed, so I have not found a public website to provide for testing. Maybe somebody knows a public website with these kind of messages.
Chrome_message.png
Chrome_message.png (86.63 KiB) Viewed 5727 times
Last edited by AHK_user on 20 Mar 2021, 05:25, edited 1 time in total.
burque505
Posts: 1731
Joined: 22 Jan 2017, 19:37

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

17 Mar 2021, 14:02

@AHK_user, I do the same thing you're doing (i.e. Send, {Enter}). I'm also curious to know if there's a better way. Are those popups modal?
Regards,
burque505
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

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

17 Mar 2021, 23:14

Does anybody know a way to handle "Messages from webpage"?
Read about Page.javascriptDialogOpening event.
Currently I just do a "Blind" Sendinput,{enter}, I was wondering if there is a better way through Selenium/controls.
You can also do it with iaccessible help or with seleniumbasic SwitchToAlert method.
burque505
Posts: 1731
Joined: 22 Jan 2017, 19:37

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

18 Mar 2021, 09:31

If anyone's willing to use the SeleniumBasic 3.141.0.0 - not many so far apparently, :D then this code may be of some use. @malcev, you'll no doubt notice right away that the syntax is different than that of the older version, but is more in line with what can be found on the web.

Code: Select all

[;https://www.autohotkey.com/boards/viewtopic.php?f=7&t=87159
SetBatchLines, -1
; Run, C:\Chromium\chrome-win\chrome.exe ; "--remote-debugging-port=9333"

; sleep, 2000

wd := ComObjCreate("SeleniumBasic.IWebDriver")
svc := ComObjCreate("SeleniumBasic.ChromeDriverService")
options := ComObjCreate("SeleniumBasic.ChromeOptions")

svc.CreateDefaultService.driverPath := "C:\Chromium" ; the webdrivers are here for me
svc.HideCommandPromptWindow := True

options.BinaryLocation := "C:\Chromium\chrome-win\chrome.exe" ; 
options.AddArgument("--start-maximized")
wd.New_ChromeDriver(svc,Options)
wd.URL := "https://www.autohotkey.com"

loop {
	ready := wd.ExecuteScript("return document.readyState")
	if (ready := "complete")
		break
	else
		sleep, 1000
}
Actions.Create(wd) ; superfluous 

wd.ExecuteScript("alert('I want to click this programmatically');")
sleep, 3000
wd.SwitchTo.Alert.Accept

sleep 5000
wd.Quit()
; This page was helpful: https://www.toolsqa.com/selenium-webdriver/alerts-in-selenium//code]
EDIT: Some experimenting is proving useful. The text from the alert can be grabbed.
Spoiler
EDIT: Here is some code showing how to send keys to popups. It is for Firefox (there seems to be bug in the Chromedriver.exe and msedgedriver.exe recently that affects SendKeys).

N.B.: The code still works (with the obvious required changes for Chrome and Edge), but you won't see the text displayed in the popup. However, the page we're testing with will show you that what you typed was actually entered).

Code: Select all

;https://www.autohotkey.com/boards/viewtopic.php?f=7&t=87159
SetBatchLines, -1

wd := ComObjCreate("SeleniumBasic.IWebDriver")
svc := ComObjCreate("SeleniumBasic.FirefoxDriverService")
options := ComObjCreate("SeleniumBasic.FirefoxOptions")

svc.CreateDefaultService ;.driverPath := "C:\Downloads\WebDrivers" ; the webdrivers are here for me
svc.HideCommandPromptWindow := True

options.AddArgument("--start-maximized")
wd.New_FirefoxDriver(svc,Options)
wd.URL := "https://demoqa.com/alerts"

loop {
	ready := wd.ExecuteScript("return document.readyState")
	if (ready := "complete")
		break
	else
		sleep, 1000
}
Actions.Create(wd) 

wd.FindElementById("promtButton").click

sleep, 2000
wd.SwitchTo.Alert.SendKeys("Winter") ; text appears for FF
sleep 2000
wd.SwitchTo.Alert.Accept
sleep 4000
msgbox, ,I will dismiss myself     , AHK filled in the prompt`nand submitted it.`nFirefox shows keys sent.`nChrome does not.`!, 2


sleep 3000
wd.Quit()
; This page was helpful: https://www.toolsqa.com/selenium-webdriver/alerts-in-selenium/
Regards,
burque505

EDIT: Code for Edge.
Spoiler
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

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

20 Mar 2021, 06:10

malcev wrote:
17 Mar 2021, 23:14
Does anybody know a way to handle "Messages from webpage"?
Read about Page.javascriptDialogOpening event.
Currently I just do a "Blind" Sendinput,{enter}, I was wondering if there is a better way through Selenium/controls.
You can also do it with iaccessible help or with seleniumbasic SwitchToAlert method.
Could anybody show an example how to use the Page.javascriptDialogOpening event with Chrome.ahk?

Example website to test on: https://the-internet.herokuapp.com/javascript_alerts
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

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

20 Mar 2021, 09:47

Read this topic from start and You will see examples how to add event listeners.
burque505
Posts: 1731
Joined: 22 Jan 2017, 19:37

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

20 Mar 2021, 10:59

This thread is deterring me from pursuing 'javascriptDialogOpening' with Chrome.ahk. That said, here is some code that at least adds an event listener.
Spoiler
Here are the relevant lines. I don't know how to get the dialog handling done yet.

Code: Select all

PageInstance.Evaluate("var clickme = document.querySelector(""button[onclick='jsPrompt()']"");")
PageInstance.Evaluate("clickme.addEventListener('click', function (event) {alert('put your handler here, I think');});")
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

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

20 Mar 2021, 16:18

Code: Select all

PageInstance := ChromeInst.GetPage(,,"callback")
PageInstance.Call("Page.enable")
return

callback(event)																				
{
   msgbox % event.method "`n" event.params.message
}
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

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

21 Mar 2021, 16:38

malcev wrote:
20 Mar 2021, 16:18

Code: Select all

PageInstance := ChromeInst.GetPage(,,"callback")
PageInstance.Call("Page.enable")
return

callback(event)																				
{
   msgbox % event.method "`n" event.params.message
}
Thanks, this let you indeed detect, read and fire a ahk script when the prompt appears.
I am not sure if it is possible to interact with it with Javascript, chause chrome seems to block javascript when waiting for the prompt but we can respond with a blind sendinput.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

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

22 Mar 2021, 07:51

AHK_user, I suggest You to read Chrome DevTools Protocol manual.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

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

22 Mar 2021, 14:04

As far I can understand from the manual, I think I need to use de Page.handleJavaScriptDialog
https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-handleJavaScriptDialog

One website I found mentioned the following solution:

Code: Select all

js =
(
Page.javascriptDialogOpening((params) => {
  Page.handleJavaScriptDialog({'accept': 'true'});
});
)
So I tried to Call and evaluate the above code, without luck.

Code: Select all

PageInst.Call("Page.handleJavaScriptDialog",{"accept": true} )
I got the following code back: {"code":-32602,"data":"Failed to deserialize params.accept - BINDINGS: bool value expected at positi...

This code also failed, but I have the impression we almost have the acorn :D
Image
Tre4shunter
Posts: 139
Joined: 26 Jan 2016, 16:05

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

22 Mar 2021, 14:11

Try:

Code: Select all

js =
(
Page.javascriptDialogOpening((params) => {
  Page.handleJavaScriptDialog({'accept': Chrome.Jxon_True()});
});
)
@AHK_user i think you need to use Chrome.Jxon_True() for a boolean parameter.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

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

22 Mar 2021, 15:23

Tre4shunter wrote:
22 Mar 2021, 14:11
Try:

Code: Select all

js =
(
Page.javascriptDialogOpening((params) => {
  Page.handleJavaScriptDialog({'accept': Chrome.Jxon_True()});
});
)
@AHK_user i think you need to use Chrome.Jxon_True() for a boolean parameter.
Wouldn`t the above code interpreted Chrome.Jxon_True() as a string?
Evaluating or calling the above code did not work.

But thanks to your comment, so I tried the following code that seemed logical:

Code: Select all

PageInst.Call("Page.handleJavaScriptDialog",{"accept": Chrome.Jxon_True()})
And I got the nice error from Chrome {"code":-32602,"message":"No dialog is showing"} :think:
:D At least it accepted the boolean parameter, but I am almost cocluding that Page.handleJavaScriptDialog is not the correct function...

(Currently I use https://the-internet.herokuapp.com/javascript_alerts for testing.)
Tre4shunter
Posts: 139
Joined: 26 Jan 2016, 16:05

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

22 Mar 2021, 15:27

Ah yes, you are totally right - i wasn't really paying attention to your original code :facepalm:

Maybe try starting here - the popup is a new 'target' window that you might need to connect to:
https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-getTargets
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

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

22 Mar 2021, 16:04

Tre4shunter wrote:
22 Mar 2021, 15:27
Ah yes, you are totally right - i wasn't really paying attention to your original code :facepalm:

Maybe try starting here - the popup is a new 'target' window that you might need to connect to:
https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-getTargets
I do not think it is a target, I tried extract the targets but could not find the specific prompt, only the webpage itself and some background pages.

Code: Select all

PageInst := Chrome.GetPage()
MsgBox, % "Result:`n" Chrome.Jxon_Dump(PageInst.Call("Target.getTargets"), "`t")
But thanks for the tip (and of course for the amazing chrome.ahk), I am learning a lot of javascript and Chrome.ahk.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: Auntiejack56 and 122 guests