Rufaydium WebDriver 1.7.2 (no selenium/websocket)

Post your working scripts, libraries and tools for AHK v1.1 and older
usafer
Posts: 6
Joined: 30 Nov 2021, 09:09

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by usafer » 01 Jul 2022, 02:31

I'm sorry because two posts in a row.
2) update chrome
3) try run driver manually if it's manage create http server successfully than close it and try Rufaydium
2. Its auto-updating for me so I don't think that issue somewhere here
3. How can I do that? Just use the Rufaydium.ahk? I don't see any reaction while trying. (but the new process in the process manager, that's right). How to create the server? Should I use another program or do you mean Rufaydium can do that?

(ATTENTION)
While I posted that I've got the message from Rufaydium about the old driver and Rufaydium fixed the problem.
As I think, webdriver keeps version in apps folder so my browser was actual, but not for webdriver. Sorry, but I didn't save the message where Rufaydium wrote me the location, but I think you know what I mean because it was Rufaydium' window.
Right now looks working

User avatar
Xeo786
Posts: 759
Joined: 09 Nov 2015, 02:43
Location: Karachi, Pakistan

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Xeo786 » 01 Jul 2022, 02:47

usafer wrote:
01 Jul 2022, 02:05
My apologies for the delay, Xeo786.
Yes, I've closed all, if Rufaydium doesn't work (every time in my case).
This is the code I've got on this topic and what I trying to use:

Code: Select all

#SingleInstance, force
;#Include %A_ScriptDir%\lib
#Include Rufaydium.ahk

ChromeDriver := A_ScriptDir "\chromedriver.exe"

url:="https://www.autohotkey.com/boards/"

; choose different driver in order to automate different Browser
Driver := new RunDriver(ChromeDriver) ; running driver
Chrome := new Rufaydium(Driver) ; this will return control over Browser

; choosing Browser Capabilities, by using Capabilities you can make custom profile for specific need
Chrome.capabilities := Capabilities.ChromeDefault 

; this is how we create session 
Page := Chrome.NewSession()
Page.Navigate(url)

GS := Chrome.getSessionByUrl(url)

Element := GS.getElementsbyXpath("//*[@id=""keywords""]")
; or 
; element:=GS.getElementbyID("keywords")

element[1].value:="Rufaydium"
element[1].SendKey(key.enter)

MsgBox, Now closing script, chrome and webdriver

GS:=""
Page := ""

;Chrome.QuitAllSessions()
driver.exit()

ExitApp
Rufaydium has been through lots of changes and Driver class and Capabilities have been merged into Rufaydium can be accessed using Capabilities methods
Please follow Github documentation for examples

following examples should work

Code: Select all

Chrome := new Rufaydium() ; default will load driver
Page := Chrome.NewSession()
Page.Navigate("https://www.autohotkey.com/")
return

f12::
Chrome.QuitAllSessions() ; close all session 
Chrome.Driver.Exit() ; then exits driver
return
"When there is no gravity, there is absolute vacuum and light travel with no time" -Game changer theory

User avatar
Xeo786
Posts: 759
Joined: 09 Nov 2015, 02:43
Location: Karachi, Pakistan

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Xeo786 » 01 Jul 2022, 04:53

Milchmann wrote:
30 Jun 2022, 06:52
Xeo786 wrote:
23 Jun 2022, 14:34
Milchmann wrote:
23 Jun 2022, 10:22
Hi,
with your last version 1 error.

Code: Select all

MsgBox % Page.QuerySelectorAll("123456").Count()  ; 
The element does not exist, yet I get 1 with Count().

and
Page.Refresh()
MsgBox, Page refresh complete
Does not work.
My bad I tried implementing error handling to .findelement()

If you Json dump the return object from queryselectorall() you will find error object saying "no such element" that is why count() says 1, I should undo the error handling,
And I haven't done anything to refresh, 🤔

I will look into this by Monday.
Count works, Thank You
But

Code: Select all

Page.Refresh()
Page.Forward()
Page.back()
does not work. As I only need this now, I have not noticed it until now
You are right, above three methods are not working, I suspect thats chromeDriver bug, Rufaydium is following W3C standard Commans and which is also enlist at chromedriver Status

They probably fix that bug in next update, for the time being, we can use following ExecuteSync

Code: Select all

#include Rufaydium.ahk
URL := "https://www.autohotkey.com/boards/index.php"
Page := GetRufaydium(URL)
msgbox, Refreshing page
Page.ExecuteSync("history.go()")
Page.Url := "https://www.autohotkey.com/boards/viewtopic.php?f=6&t=102616"
msgbox, going back
Page.ExecuteSync("history.back()")
msgbox, going forward
Page.ExecuteSync("history.forward()")
Page.Url := URL
exitapp

; GetRufaydium(URL) gets existing session  
; stops us creatting multiple sessions again and again 
; make sure do not manually close driver / chrome.driver.exit()
; by Xeo786
GetRufaydium(URL)
{
	; get chrome driver / runs chrome driver if not running, download driver if available in A_ScriptDir
	; Run Chrome Driver with default parameters and loads deafult capabilities
	Chrome := new Rufaydium() 
	Page := Chrome.getSessionByUrl(URL) ; check page (created by driver) if already exist 
	if !isobject(page) ; checcking if Session with url exist
	{
		Page := Chrome.getSession(1,1) ; try getting first session first tab
		if isobject(page) ; if exist 
			Page.NewTab() ; create new tab instead new session
		else ; if does not exist 
			Page := Chrome.NewSession() ; create new session ; Page.Exit() if any session manually closed by user which causes lag
		Page.Navigate(URL) ; navigate		
	}
	return page 
}
I made GetRufaydium() to avoid creating extra driver session while quick testing.
"When there is no gravity, there is absolute vacuum and light travel with no time" -Game changer theory

User avatar
Xeo786
Posts: 759
Joined: 09 Nov 2015, 02:43
Location: Karachi, Pakistan

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Xeo786 » 02 Jul 2022, 03:44

Xeo786 wrote:
01 Jul 2022, 04:53
Milchmann wrote:
30 Jun 2022, 06:52
Xeo786 wrote:
23 Jun 2022, 14:34
Milchmann wrote:
23 Jun 2022, 10:22
Hi,
with your last version 1 error.

Code: Select all

MsgBox % Page.QuerySelectorAll("123456").Count()  ; 
The element does not exist, yet I get 1 with Count().

and
Page.Refresh()
MsgBox, Page refresh complete
Does not work.
My bad I tried implementing error handling to .findelement()

If you Json dump the return object from queryselectorall() you will find error object saying "no such element" that is why count() says 1, I should undo the error handling,
And I haven't done anything to refresh, 🤔

I will look into this by Monday.
Count works, Thank You
But

Code: Select all

Page.Refresh()
Page.Forward()
Page.back()
does not work. As I only need this now, I have not noticed it until now
You are right, above three methods are not working, I suspect thats chromeDriver bug, Rufaydium is following W3C standard Commans and which is also enlist at chromedriver Status

They probably fix that bug in next update, for the time being, we can use following ExecuteSync

Code: Select all

#include Rufaydium.ahk
URL := "https://www.autohotkey.com/boards/index.php"
Page := GetRufaydium(URL)
msgbox, Refreshing page
Page.ExecuteSync("history.go()")
Page.Url := "https://www.autohotkey.com/boards/viewtopic.php?f=6&t=102616"
msgbox, going back
Page.ExecuteSync("history.back()")
msgbox, going forward
Page.ExecuteSync("history.forward()")
Page.Url := URL
exitapp

; GetRufaydium(URL) gets existing session  
; stops us creatting multiple sessions again and again 
; make sure do not manually close driver / chrome.driver.exit()
; by Xeo786
GetRufaydium(URL)
{
	; get chrome driver / runs chrome driver if not running, download driver if available in A_ScriptDir
	; Run Chrome Driver with default parameters and loads deafult capabilities
	Chrome := new Rufaydium() 
	Page := Chrome.getSessionByUrl(URL) ; check page (created by driver) if already exist 
	if !isobject(page) ; checcking if Session with url exist
	{
		Page := Chrome.getSession(1,1) ; try getting first session first tab
		if isobject(page) ; if exist 
			Page.NewTab() ; create new tab instead new session
		else ; if does not exist 
			Page := Chrome.NewSession() ; create new session ; Page.Exit() if any session manually closed by user which causes lag
		Page.Navigate(URL) ; navigate		
	}
	return page 
}
I made GetRufaydium() to avoid creating extra driver session while quick testing.
all though Rufaydium was following proper commands but there was payload issue, webdriver needs empty JSON to be passed for every HTTP POST method, after fixing that bug not only .Refresh() .back() .Forward() started working but there might be other command facing same bug may work now.

Thank you @Milchmann for pointing that bug :D
"When there is no gravity, there is absolute vacuum and light travel with no time" -Game changer theory

Milchmann
Posts: 112
Joined: 05 Nov 2016, 08:50

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Milchmann » 02 Jul 2022, 08:18

Xeo786 wrote:
02 Jul 2022, 03:44
all though Rufaydium was following proper commands but there was payload issue, webdriver needs empty JSON to be passed for every HTTP POST method, after fixing that bug not only .Refresh() .back() .Forward() started working but there might be other command facing same bug may work now.

Thank you @Milchmann for pointing that bug :D
Thank you for fixing the error so quickly!
Now hopefully I can also add something, namely connection to the current TAB.

Code: Select all

Chrome := new Rufaydium(ChromeDriver) ; this will return control over Browser
Page := Chrome.getSession(1)
for Index, current_tab in StrSplit(json.dump(Page.Detail()),"description"": """)
{
	if % Index > 1 and InStr(current_tab,"type"": ""page""")  ; 1 hit is always the current page in the foreground TAB Chrome
		{
			RegExMatch(current_tab,"id"": ""(.*)"", ""title",id_Tab) ; the ID of the current Tab
			id :=  "CDwindow-" id_Tab1
			RegExMatch(current_tab,"url"": ""(.*)"",",url)   ; the URL is determined, if needed
			URL_Tab := url1
			Page.Switch(id) ; Switch to the current id , the tab in the foreground is
			break
		}
}
msgbox % Page.title "`n" Page.url

Last edited by Milchmann on 02 Jul 2022, 09:38, edited 1 time in total.

User avatar
hotcheesesoup
Posts: 34
Joined: 08 May 2022, 01:41

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by hotcheesesoup » 02 Jul 2022, 09:30

@Milchmann
Does this work without having to move through each tab? I'm using a different method and it is a bit flickery whenever I change tabs since it has to compare the URL. Not a huge deal but something cleaner would be better for sure.

I was trying to use the cdwindow to find them, but couldn't figure out how to actually grab the current one instead of switching between all tabs.

Milchmann
Posts: 112
Joined: 05 Nov 2016, 08:50

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Milchmann » 02 Jul 2022, 09:37

For me it works over 99% of the time. Just try it

User avatar
hotcheesesoup
Posts: 34
Joined: 08 May 2022, 01:41

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by hotcheesesoup » 02 Jul 2022, 14:44

@Milchmann
Oh wow, it took a few minutes for me to get it going (it didn't like having an existing Chromedriver running for whatever reason), but this is very cool! It doesn't flicker when grabbing the tab like my other method.

I am using a timer to constantly update the current tab so it is always connected. It is working fine, but acts like WinActivate if I move away from Chrome. I think I'll just check if Chrome is the active window on each pass and that should solve the issue.

Very very cool Milchmann! Thanks a lot for figuring this out! You should definitely do a pull request on GitHub to have this implemented.

User avatar
hotcheesesoup
Posts: 34
Joined: 08 May 2022, 01:41

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by hotcheesesoup » 02 Jul 2022, 14:57

@Milchmann
When opening a new tab, it will automatically make the new tab the active tab. Typically, middle-clicking a link opens a new tab without activating it.

Can you think of a way to make it behave like that? Not the end of the world, but would be helpful!

Thanks!

Milchmann
Posts: 112
Joined: 05 Nov 2016, 08:50

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Milchmann » 03 Jul 2022, 02:48

hotcheesesoup wrote:
02 Jul 2022, 14:57
@Milchmann
When opening a new tab, it will automatically make the new tab the active tab. Typically, middle-clicking a link opens a new tab without activating it.

Can you think of a way to make it behave like that? Not the end of the world, but would be helpful!

Thanks!
I think, this is a way --> not tested

Code: Select all

Tab := session.GetTabs().length()
a := json.dump(session.Detail())
element.click() ;  middle-clicking a link opens a new tab

while !(session.GetTabs().length() > Tab)
sleep, 300

sleep, 200
for Index, current_tab in StrSplit(json.dump(session.Detail()),"description"": """)
{
	if % Index > 1 and InStr(current_tab,"type"": ""page""")  
		( 
			RegExMatch(current_tab,"id"": ""(.*)"", ""title",id_Tab) 
				if !instr(id_Tab1,Tab)  ; if the ID is not contained in the stored tab variable
					{
						id :=  "CDwindow-" id_Tab1
						session.Switch(id)
						break
					{	
						
						
		}		
}
msgbox % session.title "`n" session.url

User avatar
Xeo786
Posts: 759
Joined: 09 Nov 2015, 02:43
Location: Karachi, Pakistan

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Xeo786 » 04 Jul 2022, 04:41

Milchmann wrote:
02 Jul 2022, 08:18
Xeo786 wrote:
02 Jul 2022, 03:44
all though Rufaydium was following proper commands but there was payload issue, webdriver needs empty JSON to be passed for every HTTP POST method, after fixing that bug not only .Refresh() .back() .Forward() started working but there might be other command facing same bug may work now.

Thank you @Milchmann for pointing that bug :D
Thank you for fixing the error so quickly!
Now hopefully I can also add something, namely connection to the current TAB.

Code: Select all

Chrome := new Rufaydium(ChromeDriver) ; this will return control over Browser
Page := Chrome.getSession(1)
for Index, current_tab in StrSplit(json.dump(Page.Detail()),"description"": """)
{
	if % Index > 1 and InStr(current_tab,"type"": ""page""")  ; 1 hit is always the current page in the foreground TAB Chrome
		{
			RegExMatch(current_tab,"id"": ""(.*)"", ""title",id_Tab) ; the ID of the current Tab
			id :=  "CDwindow-" id_Tab1
			RegExMatch(current_tab,"url"": ""(.*)"",",url)   ; the URL is determined, if needed
			URL_Tab := url1
			Page.Switch(id) ; Switch to the current id , the tab in the foreground is
			break
		}
}
msgbox % Page.title "`n" Page.url

Thank again I haven't noticed that we can get active tab using JSON/LIST, therefore I've just implemented this
Following example will return active tab

Code: Select all

Chrome := new Rufaydium()
Page := Chrome.getSession(1)
msgbox, % Page.Title "`n" Page.Url
return
and at any stage you can get active tab by doing

Code: Select all

Session.ActiveTab()
"When there is no gravity, there is absolute vacuum and light travel with no time" -Game changer theory

User avatar
hotcheesesoup
Posts: 34
Joined: 08 May 2022, 01:41

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by hotcheesesoup » 04 Jul 2022, 17:00

@Milchmann
I can't get that to work, so I'm probably doing something wrong on my end. Not a big deal at all. Thanks for trying!

@Xeo786
Just tested it out and it works great! Seems very similar to Milchmann's solution. It has the same issue of activating the new tab, but I'm thinking this is a byproduct of the way I'm constantly using a timer to get the active tab. Definitely just a minor issue.

Thanks a lot!

User avatar
Xeo786
Posts: 759
Joined: 09 Nov 2015, 02:43
Location: Karachi, Pakistan

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Xeo786 » 06 Jul 2022, 01:42

hotcheesesoup wrote:
04 Jul 2022, 17:00
It has the same issue of activating the new tab, but I'm thinking this is a byproduct of the way I'm constantly using a timer to get the active tab. Definitely just a minor issue.
So you want to create new Tab without activating it?
just added that option

Code: Select all

page.NewTab(0)  ; will create a tab without activating it
page.NewWindow(0) ; will create a new window without activating/switing-to it
"When there is no gravity, there is absolute vacuum and light travel with no time" -Game changer theory

pAnDeLa
Posts: 6
Joined: 02 Apr 2017, 03:33

Re: Rufaydium WebDriver (no selenium/websocket)

Post by pAnDeLa » 06 Jul 2022, 20:49

Tre4shunter wrote:
21 Apr 2022, 10:10
using "--log-PATH=c:\myfile.log --enable-chrome-logs" does work to log the console messages from a web page...but whenever I add those two switches, for some reason it continuously pops up multiple cmd windows for chrome.exe which are blank.

I've not yet figured out how to prevent those cmd windows from appearing wen using the above switches...
Are you able to share a sample of this working in Rufaydium ? I haven't been able to get those flags to do anything. Callback functions in Rufaydium is priceless functionality I'm sure we could all use :salute:

User avatar
Xeo786
Posts: 759
Joined: 09 Nov 2015, 02:43
Location: Karachi, Pakistan

Re: Rufaydium WebDriver (no selenium/websocket)

Post by Xeo786 » 07 Jul 2022, 01:56

pAnDeLa wrote:
06 Jul 2022, 20:49
Tre4shunter wrote:
21 Apr 2022, 10:10
using "--log-PATH=c:\myfile.log --enable-chrome-logs" does work to log the console messages from a web page...but whenever I add those two switches, for some reason it continuously pops up multiple cmd windows for chrome.exe which are blank.

I've not yet figured out how to prevent those cmd windows from appearing wen using the above switches...
Are you able to share a sample of this working in Rufaydium ? I haven't been able to get those flags to do anything. Callback functions in Rufaydium is priceless functionality I'm sure we could all use :salute:
I haven't tried parsing Logs like these, there is CLogTailer.ahk which can trigger callbacks using logs but parsing these kind of logs is not simple,
check out logs
Spoiler
Here the Code to Rundriver to generate event logs from driver and Broswer

Code: Select all

#include Rufaydium.ahk
URL := "https://www.autohotkey.com/boards"
Logfile := a_scriptdir "\Events.txt"
while fileexist(Logfile)
	FileDelete, % Logfile
	
Chrome := new Rufaydium(,"--port=9515" chr(34) " " chr(34) "--log-path=" Logfile chr(34) " " chr(34) "--log-level=ALL")
Page := Chrome.NewSession()
Page.Url := URL
run % Logfile
this will generated Browser log

Code: Select all

#include Rufaydium.ahk
URL := "https://www.autohotkey.com/boards"
Logfile := a_scriptdir "\Events.txt"
Chrome := new Rufaydium()
;Chrome.Capabilities.addArg("--log-level=0") ; change log level
Chrome.Capabilities.addArg("--log-file=" Logfile)
Page := Chrome.NewSession()
Page.Url := URL
Page.QuerySelector("#keywords").sendkey("ABC/")
run % Logfile
I haven't studied these logs very well, I read somewhere that selenium uses event logs from driver/broswer to trigger callbacks
"When there is no gravity, there is absolute vacuum and light travel with no time" -Game changer theory

pAnDeLa
Posts: 6
Joined: 02 Apr 2017, 03:33

Re: Rufaydium WebDriver (no selenium/websocket)

Post by pAnDeLa » 09 Jul 2022, 05:27

Xeo786 wrote:
07 Jul 2022, 01:56
pAnDeLa wrote:
06 Jul 2022, 20:49
Tre4shunter wrote:
21 Apr 2022, 10:10
using "--log-PATH=c:\myfile.log --enable-chrome-logs" does work to log the console messages from a web page...but whenever I add those two switches, for some reason it continuously pops up multiple cmd windows for chrome.exe which are blank.

I've not yet figured out how to prevent those cmd windows from appearing wen using the above switches...
Are you able to share a sample of this working in Rufaydium ? I haven't been able to get those flags to do anything. Callback functions in Rufaydium is priceless functionality I'm sure we could all use :salute:
I haven't tried parsing Logs like these, there is CLogTailer.ahk which can trigger callbacks using logs but parsing these kind of logs is not simple,
check out logs
Spoiler
Here the Code to Rundriver to generate event logs from driver and Broswer

Code: Select all

#include Rufaydium.ahk
URL := "https://www.autohotkey.com/boards"
Logfile := a_scriptdir "\Events.txt"
while fileexist(Logfile)
	FileDelete, % Logfile
	
Chrome := new Rufaydium(,"--port=9515" chr(34) " " chr(34) "--log-path=" Logfile chr(34) " " chr(34) "--log-level=ALL")
Page := Chrome.NewSession()
Page.Url := URL
run % Logfile
this will generated Browser log

Code: Select all

#include Rufaydium.ahk
URL := "https://www.autohotkey.com/boards"
Logfile := a_scriptdir "\Events.txt"
Chrome := new Rufaydium()
;Chrome.Capabilities.addArg("--log-level=0") ; change log level
Chrome.Capabilities.addArg("--log-file=" Logfile)
Page := Chrome.NewSession()
Page.Url := URL
Page.QuerySelector("#keywords").sendkey("ABC/")
run % Logfile
I haven't studied these logs very well, I read somewhere that selenium uses event logs from driver/broswer to trigger callbacks
Thanks for getting back, I did a lot of digging and was able to find a flag that actually logs js console messages!
That flag being --webview-log-js-console-messages. While the method you posted into getting the browser log is great and yields far more detailed information, I have a quick solution as well :D The chrome_debug.log file generated by chrome is deleted every time you reopen chrome too. If I recall you must use the Default or current Chrome Profile in Rufaydium as well.

Here's a working example of js callbacks in Rufaydium & Chrome, thanks again for this amazing library 8-)

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 Rufaydium.ahk
#SingleInstance,Force


if (A_Args.Length() = 0) {
	Run, "C:\Program Files\AutoHotkey\AutoHotkeyU64.exe" %A_ScriptFullPath% 1
	ExitApp
}


Chrome_Log := new CLogTailer("C:\Users\uername\AppData\Local\Google\Chrome\User Data\chrome_debug.log", Func("ReadLog"))
ReadLog(Console_Output){
	;ToolTip % "New line added @ " A_TickCount ": " text
	if RegExMatch(Console_Output,"hello world!") { 
		msgbox, Houston we have lift off!
		gosub, DoStuff
	}
}

/*
	Load "chromedriver.exe" from "A_ScriptDir"
	In case Driver is not yet available, it will Download "chromedriver.exe" into "A_ScriptDir"
	before starting the Driver.
*/

ChromeInst := new Rufaydium("chromedriver.exe", "--port=9515")
ChromeInst.capabilities.setUserProfile("Default") ;use Default chrome profile
ChromeInst.capabilities.addArg(" --enable-logging ") ;enable chrome_debug.log file
ChromeInst.capabilities.addArg(" --v=0 ") ;needed for above logging flag to work
ChromeInst.capabilities.addArg(" --webview-log-js-console-messages ") ;this undocumented flag is the peace de la resistance we need for js/console to ahk callbacks to work

/*
	Create new session if WebBrowser Version Matches the Webdriver Version.
	It will ask to download the compatible WebDriver if not present.
*/

Page := ChromeInst.NewSession()
;Page := ChromeInst.NewSession("C:\Program Files\Google\Chrome\Application\chrome.exe")
;Page.CDP.call("Console.enable") ;not needed in this case
Page.Navigate("https://www.autohotkey.com/docs/AutoHotkey.htm") ; navigate to url
sleep, 1000

gosub, InjectJS
return

DoStuff:
Settings := Page.getElementsByClassName("settings")[0] ;open settings page
Settings.Click()
msgbox, We did stuff!
return


;https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
;https://www.autohotkey.com/boards/viewtopic.php?style=17&p=306235#p306235
InjectJS:
JS_MutationObserver =
(
function init() {
  if (window.MutationObserver) {
    startMutationObserver();
  } else {
    startMutationEvents();
  }
}

function startMutationObserver() {
  // target node to be observed
  var target = document.querySelector('body');
  // mutation observer config object with the listeners configuration
  var config = listenOnlyAttributeChanges();

  // mutation observer instantiation
  var mutationObs = new MutationObserver(callbackAttributeChange);

  // observe initialization
  mutationObs.observe(target, config);
}

function listenOnlyAttributeChanges() {
  return {
    attributes: true,
    childList: true,
    subtree: true
  };
}

function callbackAttributeChange(mutations, mutationObs) {
  for (var i = 0, length = mutations.length; i < length; i++) {
    var mutation = mutations[i];
    if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
      var target = mutation.target;
      console.log(target.id + target.style.display);
      console.log("---" + target.id + target.class);
	 
	 //test
	 console.log("hello world!");
    }
  }
}

var addedNodes = 0;
var colorpage = false;
init();
)

;Inject Mutation Observer
Page.CDP.Evaluate(JS_MutationObserver)
return


F12::
ChromeInst.QuitAllSessions() ; close all session 
ChromeInst.Driver.Exit() ; then exits driver
Process,Close,chromedriver.exe ;force closer driver
ExitApp


;https://www.autohotkey.com/boards/viewtopic.php?t=47894#p215692
class CLogTailer {
	__New(logfile, callback){
		this.file := FileOpen(logfile, "r-d")
		this.callback := callback
		; Move seek to end of file
		this.file.Seek(0, 2)
		fn := this.WatchLog.Bind(this)
		SetTimer, % fn, 100
	}
	
	WatchLog(){
		Loop {
			p := this.file.Tell()
			l := this.file.Length
			line := this.file.ReadLine(), "`r`n"
			len := StrLen(line)
			if (len){
				RegExMatch(line, "[\r\n]+", matches)
				if (line == matches)
					continue
				this.callback.Call(Trim(line, "`r`n"))
			}
		} until (p == l)
	}
}

Milchmann
Posts: 112
Joined: 05 Nov 2016, 08:50

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Milchmann » 11 Jul 2022, 01:06

Hi @Xeo786,

You have an interesting function in your Rufaydium code ( Session["capabilities","chrome"]). That is better than regexmatch/regexreplace.
Can you provide me with a reference to this function?

Code: Select all

for example, Session in Chrome.Sessions()
{
chromeOptions := Session["capabilities","chrome"]
MsgBox %  json.dump(chromeOptions)
MsgBox % chromeOptions.userDataDir
}
Thank You.

pAnDeLa
Posts: 6
Joined: 02 Apr 2017, 03:33

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by pAnDeLa » 12 Jul 2022, 14:47

I see there are functions for dragging and dropping web elements, but is it possible to simulate dropping a file onto a droppable webpage element or file input element, via Rufaydium?

User avatar
Xeo786
Posts: 759
Joined: 09 Nov 2015, 02:43
Location: Karachi, Pakistan

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by Xeo786 » 13 Jul 2022, 00:36

Milchmann wrote:
11 Jul 2022, 01:06
Hi @Xeo786,

You have an interesting function in your Rufaydium code ( Session["capabilities","chrome"]). That is better than regexmatch/regexreplace.
Can you provide me with a reference to this function?

Code: Select all

for example, Session in Chrome.Sessions()
{
chromeOptions := Session["capabilities","chrome"]
MsgBox %  json.dump(chromeOptions)
MsgBox % chromeOptions.userDataDir
}
Thank You.
Chrome.Sessions() is a non-W3C standard/chromium limited command, which gets the detail of every session created, Rufaydium uses that to access existing sessions, you just JSON.dump() whole object to understand the object's structure, then access detail.

Code: Select all

MsgBox %  clipboard := json.dump(Chrome.Sessions(),1)
pAnDeLa wrote:
09 Jul 2022, 05:27
Thanks for getting back, I did a lot of digging and was able to find a flag that actually logs js console messages!
That flag being --webview-log-js-console-messages. While the method you posted into getting the browser log is great and yields far more detailed information, I have a quick solution as well :D The chrome_debug.log file generated by chrome is deleted every time you reopen chrome too. If I recall you must use the Default or current Chrome Profile in Rufaydium as well.

Here's a working example of js callbacks in Rufaydium & Chrome, thanks again for this amazing library 8-)

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 Rufaydium.ahk
#SingleInstance,Force


if (A_Args.Length() = 0) {
	Run, "C:\Program Files\AutoHotkey\AutoHotkeyU64.exe" %A_ScriptFullPath% 1
	ExitApp
}


Chrome_Log := new CLogTailer("C:\Users\uername\AppData\Local\Google\Chrome\User Data\chrome_debug.log", Func("ReadLog"))
ReadLog(Console_Output){
	;ToolTip % "New line added @ " A_TickCount ": " text
	if RegExMatch(Console_Output,"hello world!") { 
		msgbox, Houston we have lift off!
		gosub, DoStuff
	}
}

/*
	Load "chromedriver.exe" from "A_ScriptDir"
	In case Driver is not yet available, it will Download "chromedriver.exe" into "A_ScriptDir"
	before starting the Driver.
*/

ChromeInst := new Rufaydium("chromedriver.exe", "--port=9515")
ChromeInst.capabilities.setUserProfile("Default") ;use Default chrome profile
ChromeInst.capabilities.addArg(" --enable-logging ") ;enable chrome_debug.log file
ChromeInst.capabilities.addArg(" --v=0 ") ;needed for above logging flag to work
ChromeInst.capabilities.addArg(" --webview-log-js-console-messages ") ;this undocumented flag is the peace de la resistance we need for js/console to ahk callbacks to work

/*
	Create new session if WebBrowser Version Matches the Webdriver Version.
	It will ask to download the compatible WebDriver if not present.
*/

Page := ChromeInst.NewSession()
;Page := ChromeInst.NewSession("C:\Program Files\Google\Chrome\Application\chrome.exe")
;Page.CDP.call("Console.enable") ;not needed in this case
Page.Navigate("https://www.autohotkey.com/docs/AutoHotkey.htm") ; navigate to url
sleep, 1000

gosub, InjectJS
return

DoStuff:
Settings := Page.getElementsByClassName("settings")[0] ;open settings page
Settings.Click()
msgbox, We did stuff!
return


;https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
;https://www.autohotkey.com/boards/viewtopic.php?style=17&p=306235#p306235
InjectJS:
JS_MutationObserver =
(
function init() {
  if (window.MutationObserver) {
    startMutationObserver();
  } else {
    startMutationEvents();
  }
}

function startMutationObserver() {
  // target node to be observed
  var target = document.querySelector('body');
  // mutation observer config object with the listeners configuration
  var config = listenOnlyAttributeChanges();

  // mutation observer instantiation
  var mutationObs = new MutationObserver(callbackAttributeChange);

  // observe initialization
  mutationObs.observe(target, config);
}

function listenOnlyAttributeChanges() {
  return {
    attributes: true,
    childList: true,
    subtree: true
  };
}

function callbackAttributeChange(mutations, mutationObs) {
  for (var i = 0, length = mutations.length; i < length; i++) {
    var mutation = mutations[i];
    if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
      var target = mutation.target;
      console.log(target.id + target.style.display);
      console.log("---" + target.id + target.class);
	 
	 //test
	 console.log("hello world!");
    }
  }
}

var addedNodes = 0;
var colorpage = false;
init();
)

;Inject Mutation Observer
Page.CDP.Evaluate(JS_MutationObserver)
return


F12::
ChromeInst.QuitAllSessions() ; close all session 
ChromeInst.Driver.Exit() ; then exits driver
Process,Close,chromedriver.exe ;force closer driver
ExitApp


;https://www.autohotkey.com/boards/viewtopic.php?t=47894#p215692
class CLogTailer {
	__New(logfile, callback){
		this.file := FileOpen(logfile, "r-d")
		this.callback := callback
		; Move seek to end of file
		this.file.Seek(0, 2)
		fn := this.WatchLog.Bind(this)
		SetTimer, % fn, 100
	}
	
	WatchLog(){
		Loop {
			p := this.file.Tell()
			l := this.file.Length
			line := this.file.ReadLine(), "`r`n"
			len := StrLen(line)
			if (len){
				RegExMatch(line, "[\r\n]+", matches)
				if (line == matches)
					continue
				this.callback.Call(Trim(line, "`r`n"))
			}
		} until (p == l)
	}
}
Thanks That example is awesome,
pAnDeLa wrote:
12 Jul 2022, 14:47
I see there are functions for dragging and dropping web elements, but is it possible to simulate dropping a file onto a droppable webpage element or file input element, via Rufaydium?
You can check web-driver actions or Rufaydium's Session.Actions() actually I am planning to write action class to make this stuff easy.
"When there is no gravity, there is absolute vacuum and light travel with no time" -Game changer theory

pAnDeLa
Posts: 6
Joined: 02 Apr 2017, 03:33

Re: Rufaydium WebDriver 1.6.3 (no selenium/websocket)

Post by pAnDeLa » 13 Jul 2022, 01:12

pAnDeLa wrote:
12 Jul 2022, 14:47
I see there are functions for dragging and dropping web elements, but is it possible to simulate dropping a file onto a droppable webpage element or file input element, via Rufaydium?
You can check web-driver actions or Rufaydium's Session.Actions() actually I am planning to write action class to make this stuff easy.
Oh nice thx, those are great resources! And I should've read the Rufaydium docs more though lol,
drag and drop simulation/substitution can also be done with:

Code: Select all

;simulate drag and drop file via file input element
filelocation := "C:\Users\username\Pictures\image.png" ;set file path
UploadFile := Page.querySelectorAll(".chatEntry input[name=fileupload")[0] ;select file input element
UploadFile.Sendkey(StrReplace(filelocation,"\","/")) ;if Element is input element then file location can be set using SendKey()

Post Reply

Return to “Scripts and Functions (v1)”