; Functions ;------------------------------------------------ ; -------------------------------Tab Navigation & Activation------------------------------- CheckCurrentTabForCurrentSite(){ try CurrentTabURL := driver.url if(!InStr(CurrentTabURL, CurrentSite)){ Message = Chromedriver failed to switch to %CurrentSite%. Please see errorlog for website it got stuck on. SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") return "Failed" } } /* */ GetCurrentTabURlBase(){ try, TabURL := driver.url TabURL := ExtractBaseURL(TabURL) return TabURL } ExtractBaseURL(URL){ URLBase := StrReplace(URL,"https://","") ; remove beginning of URL URLBase := StrReplace(URLBase,"http://","") ; remove beginning of URL URLBase := StrReplace(URLBase, "www.","") ; remove www if there 1 URLBase := StrSplit(URLBase, "/") ; remove text after url base URLBase := URLBase[1] return URLBase } NavigateFromBaseURLTo(URL,PageTitle := "TodoDeleteme"){ ; if not connected to selenium chrome, then re-connect. This will also generate an array of all open chrome tabs if(!DriverStatus){ Status := CheckSeleniumDriver() if(Status){ Message = Failed to Connect to Chrome. Please Check for any open dialog boxes or ChromeDriver being out of date. SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") Return "Failed" } } ; extract Base URL from Full URL URLBase := ExtractBaseURL(URL) ; if URLBase is NOT a substring within any of the values in the array if(!HasSubstringVal(ChromeTabsURLArray, URLBase)) { ; DevModeMsgBox("Creating new tab") Message = Tab for %urlBase% does not exist. Creating new tab with URL: %URL% try, run "%ChromeFilepath%" "%URL%" ChromeTabsURLArray.Push(URL) ; Append the new url to the array NewTabCreated := 1 sleep, 1000 } else, { Message = %URLBase% is within ChromeTabsURLArray. Trying to Activate. SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") } ; message = NewTabCreated: %NewTabCreated% ; DevModeMsgBox(message) status := ActivateChromeTab(URLBase) if(Status = "Failed"){ try currentURL := driver.url Message = Failed to switch active tab to %URLBase%. Current tab is: %currentURL% SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") CheckForAlerts() ; create a new tab and try to switch to it again Message = Creating new tab with URL: %URL% SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") try, run "%ChromeFilepath%" "%URL%" ChromeTabsURLArray.Push(URL) ; Append the new url to the array NewTabCreated := 1 sleep, 1000 status := ActivateChromeTab(URL) if(Status = "Failed"){ Message = Failed to activate tab for %urlBase% after 2 atteppts. Chrome stuck on a dialog box of some sort? SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") Return "Failed" } } ; message = ActivateChromeTab Status: %status% ; DevModeMsgBox(message) if(!NewTabCreated){ ; if re-using a tab then we want to re-navigate to URL because it might be the wrong page ; Double check that the current tab URL matches the url base try, CurrentTabURl := driver.url ; Message = Reusing Tab. `nCurrentTabURl: %CurrentTabURl%`nURL Navigating to: %URL% ; DevModeMsgBox(Message) ; DevModeMsgBox("getting url") try driver.Get(URL) ;Open selected URL catch e { Message = Failed to Navigate to URL in pre-existing tab`nPlease See Error #5648 for code section SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") ; SaveDriverURLOFErrorPage() ; Return ; msgbox, error caught. trying something try driver.switchToalert().accept() try driver.Get(URL) ;Open selected URL catch e { Message = Failed to Navigate to URL: %URL%. Please Check for any open dialog boxes or ChromeDriver being out of date. SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") Return "Failed" } } try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding } Return } ; -------------------------------ActivateChromeTab------------------------------- ActivateChromeTab(URL){ ; Extract Base URL if necessary if(InStr(URL, "/")){ URLBase := ExtractBaseURL(URL) } else, { URLBase := URL } ; Message = Finding Tab with URL base: %URLBase% ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") ; DevModeMsgBox(Message) ; if not connected to selenium chrome, then re-connect if(!DriverStatus){ Status := CheckSeleniumDriver() if(Status) Return "Failed" } TabFoundSuccessfully := NumberOfTabActivationLoops := ChromeTabsURLArray.Length() ; Message := "NumberOfTabActivationLoops: " NumberOfTabActivationLoops ; DevModeMsgBox(Message) ; NumberOfTabLoops := Driver.Windows.Count + 2 Message = Looping through tabs to activate with: %URLBase% SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") loop % NumberOfTabActivationLoops { ; loop through tabs to find matching tab try driver.SwitchToNextWindow() ; sleep, 1000 ; msgbox, looping through tabs try CurrentTabTitle := driver.window.title try CurrentTabURL := driver.Url if(InStr(CurrentTabURL, URLBase)){ ; Message = Found Tab:.`n%CurrentTabTitle% = %PageTitle%`n%CurrentTabURL% = %URLBase% ; DevModeMsgBox(message) TabFoundSuccessfully := 1 ; msgbox %CurrentTabTitle% = %PageTitle% ; msgbox %CurrentTabURL% = %URL% return } ; / loop through tabs } Message = ActivateChromeTab function failed to activate tab for %urlBase% after looping through %NumberOfTabActivationLoops% tabs SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") return "Failed" } CheckForAlerts(){ Message = Checking for Any Obstructing Alerts in Chrome SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") status := 1 try driver.SwitchToAlert() catch e { status := 0 return 0 } if(status){ ; msgbox, alert found ; Message = Page Alert Found. Dismissing. Message = Page Alert Found. Accepting. SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") try driver.switchToalert().accept() ; try driver.switchToalert().dismiss() return "True" } } CheckURLForSubstring(Substring){ try CurrentTabURL := driver.url if(InStr(CurrentTabURL, Substring)) return "True" else, return } ; End of Function ; -------------------------------/NavigateFromBaseURL------------------------------- SaveDriverURL(){ ; save the url of the result page. That way if a tab is not found for a site, we can open up a tab from this tab instead of middle of nowhere. That way we can keep the tabs together try LastWebsitePostURL := driver.URL return LastWebsitePostURL } ; -------------------------------SChrome_Get------------------------------- SChrome_Get(URL := "", Profile := "Profile 1", IP_Port := "127.0.0.1:9222"){ IP_Port_Nr := RegExReplace(IP_Port, ".*:(\d*)", "$1") if WinExist("ahk_exe Chrome.exe"){ WinGet, pid, PID, ahk_exe chrome.exe for item in ComObjGet("winmgmts:").ExecQuery("SELECT * FROM Win32_Process WHERE ProcessId='" pid "'"){ if RegExMatch(item.CommandLine, "i)--remote-debugging-port=\K\d+", port){ break } } if (Port=""){ MsgBox, 36, ,Chrome Needs to be started in debugging mode in order for the Uploader to control it with Selenium.`nAutomatically restart Chrome in debug mode to enable a connection? IfMsgBox, Yes { Message = Restarting Chrome in Debug Mode SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") While(WinExist("ahk_exe chrome.exe")) { WinClose, ahk_exe chrome.exe } Process, WaitClose, chrome.exe } Else{ Msgbox, 4096, Error, Cannot connect to Chrome profile if it is Not running in debug mode. Program Exiting ExitApp ; @todo: Make this error out to the script result screen } } } ; ; yuriy's settings ; IniRead, ChromeFilepath, C:\Users\%A_username%\Documents\Autohotkey\Lib\ScriptSettings.ini, Selenium, %A_Computername%, %A_Space% ; ; Establish Variable with Filepath to be used throughout the script ; if(ChromeFilepath = ""){ if(FileExist("C:\Program Files\Google\Chrome\Application\chrome.exe")){ ChromeFilepath = C:\Program Files\Google\Chrome\Application\chrome.exe } else if (FileExist("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe")){ ChromeFilepath = C:\Program Files (x86)\Google\Chrome\Application\chrome.exe } if(ChromeFilepath = ""){ Message = Failed to find chrome.exe in the usual locations. SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") MsgBox 0x30, Error!, Unable to find Chrome.exe in the usual locations. `nScript Exiting. ExitApp } if(!winExist("ahk_exe chrome.exe")){ run, %ChromeFilepath% --remote-debugging-port=%IP_Port_Nr% %URL% } Driver := ComObjCreate("Selenium.ChromeDriver") Driver.SetCapability("debuggerAddress", IP_Port) try Driver.Start() catch e { ShowSeleniumErrorMsgbox() } ; end of catch ; Save current chrome version to ini file return Driver } ; -------------------------------/SChrome_Get------------------------------- /* */ ShowSeleniumErrorMsgbox(){ GetChromeVersionCommand = powershell (Get-Item '%ChromeFilepath%').VersionInfo.ProductVersion Chromeversion := RunCMD(GetChromeVersionCommand) ChromeVersion := StrReplace(ChromeVersion, "`n", "") ; Clipboard := ChromeVersion ; Msgbox % "Chromeversion: " Chromeversion IniRead, PreviousWorkingChromeVersion, Settings.ini, Misc, ChromeVersion, %A_Space% ; IniWrite, %ChromeVersion%, Settings.ini, Misc, ChromeVersion ; msgbox, failed to connect to Chrome for some reason. ; Message = Failed to Connect to Chrome. Most likely problem is either Chrome has some sort of dialogue box open or ChromeDriver needs to be updated. ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") OnMessage(0x44, "OnMsgBoxChromeDriverFailed") MsgBox 0x40043, Error, Failed to Connect to Chrome. `nMost likely issue is either Chrome has some sort of dialogue box open or ChromeDriver needs to be updated.`n`nClick "Reload" to reload the script to try again`nClick "ChromeDriver" to open up the ChromeDriver download page. `n`nClick "Instructions" to open up .pdf file with instructions for updating chromedriver.exe`n`nPossibly Helpful Info:`nCurrent Chrome Version: %Chromeversion%Chrome Version of Last Successfull Upload: %PreviousWorkingChromeVersion% OnMessage(0x44, "") IfMsgBox Yes, { ; Reload script Reload } Else IfMsgBox No, { run, https://chromedriver.chromium.org/downloads ExitApp ; open chromedriver site } Else IfMsgBox Cancel, { URL = https://freedomainplaylists.com/wp-content/FreedomainScripts/Update`%20Selenium`%20ChromeDriver.pdf Filepath = %A_ScriptDir%\Lib\Update Selenium ChromeDriver.pdf if(!FileExist(Filepath)){ UrlDownloadToFile, %URL%, %Filepath% run, %Filepath% } ExitApp } } ; -------------------------------HasVal------------------------------- ; Function needed for finding a value in an array HasVal(haystack, needle) { if !(IsObject(haystack)) || (haystack.Length() = 0) return 0 for index, value in haystack if (value = needle) return index return 0 } ; -------------------------------/HasVal------------------------------- HasSubstringVal(haystack, needle) { if !(IsObject(haystack)) || (haystack.Length() = 0) return 0 for index, value in haystack if (InStr(value, Needle)) return index return 0 } ; SubStr(String, StartingPos [, Length]) ; InStr(value, Needle) /* */ ; Various functions used to control Selenium, Chrome and Chrome.AHK ;---Javascript--- ;------------------------------------------------ JS_TryToExecute(JsToExecute,NumberofAttempts := 1,SleepLength:=1000){ loop, %NumberofAttempts% { try driver.executeScript(JsToExecute) catch e { Continue } Return } Return "Failed" } js_SendAndCheckWithQuerySelector(Selector,ValueToCheck:="value",SleepLength:=1000,JSStringText:="TEXT"){ js = document.querySelector("%Selector%").value = "%JSStringText%"; try driver.executeScript(js) sleep, %SleepLength% js = return document.querySelector("#title").value; try, status := driver.executeScript(js) ; DevModeMsgBox(status) if(Status = "") return "Failed" else, return "" } ; ValueToCheckOptions = innertext,textContent,InnerHTML,outerHTML,value,href,option value js_SendAndCheckWithClassName(ClassName:="",ClassIndexNum:=0,ValueToCheck:="textContent",SleepLength:=1000,JSStringText:="TEXT"){ jsSend = document.getElementsByClassName('%ClassName%')[%ClassIndexNum%].value = "%JSStringText%"; try driver.executeScript(jsSend) sleep, %SleepLength% jsCheck = return document.getElementsByClassName('%ClassName%')[%ClassIndexNum%].%ValueToCheck%; try Status := driver.executeScript(jsCheck) ; Msgbox % "Status: " Status if(Status = "") return "Failed" else, return "" } ; ValueToCheckOptions = innertext,textContent,InnerHTML,outerHTML,value,href,option value js_SendAndCheckWithNAME(Element:="",IndexNum:=0,ValueToCheck:="textContent",SleepLength:=1000,JSStringText:=""){ jsSend = document.getElementsByName('%Element%')[%IndexNum%].value = "%JSStringText%"; /*Clipboard := jsSend Msgbox % "jsSend: " jsSend */ ; document.getElementsByClassName('%ClassName%')[%ClassIndexNum%].value = "%JSStringText%"; try driver.executeScript(jsSend) sleep, %SleepLength% jsCheck = return document.getElementsByName('%Element%')[%IndexNum%].%ValueToCheck%; ; Clipboard := jscheck ; Msgbox % "jsCheck: " jsCheck try Status := driver.executeScript(jsCheck) ; Msgbox % "Status: " Status if(Status = "") return "Failed" else, return "" } ; ValueToCheckOptions = innertext,textContent,InnerHTML,outerHTML,value,href,option value js_SendAndCheckWithID(Element:="",ValueToCheck:="textContent",SleepLength:=1000,JSStringText:=""){ ; Msgbox % "Element: " Element ; Msgbox % "JSStringText: " JSStringText jsSend = document.getElementById('%Element%').value = "%JSStringText%"; ; Clipboard := jsSend ; Msgbox % "jsSend: " jsSend try driver.executeScript(jsSend) ; Msgbox % "JSStringText: " JSStringText sleep, %SleepLength% jsCheck = return document.getElementById('%Element%').%ValueToCheck%; try Status := driver.executeScript(jsCheck) if(Status = "") return "Failed" else, return "" } ;---\Javascript--- ;------------------------------------------------ ;---Selenium--- ;------------------------------------------------ ; When called these will try multiple times to click/input into a web element Selenium_LoopToClickID(IDName,NumOfLoops:=1,SleepLength:=1000){ loop, %NumOfLoops% { try driver.findElementsByID(IDName).item[1].click() ; Click on "upload image" button catch e { if(A_index = NumOfLoops){ Return "Failed" } sleep, %SleepLength% Continue } Return } } Selenium_LoopToClickName(ElementName,NumOfLoops:=1,SleepLength:=1000){ loop, %NumOfLoops% { try driver.findElementsByName(ElementName).item[1].click() catch e { if(A_index = NumOfLoops){ Return "Failed" } sleep, %SleepLength% Continue } Return } } Selenium_LoopToSendValueToID(IDName,NumOfLoops:=1,SleepLength:=1000,StringTextContent:=""){ loop, %NumOfLoops% { try driver.findElementsByID(IDName).item[1].sendKeys(StringTextContent) ; Click on "upload image" button catch e { if(A_index = NumOfLoops){ Return "Failed" } sleep, %SleepLength% Continue } Return } } ; Selenium_LoopToSendValueByName(ElementName:="NAME",NumOfLoops:=2,SleepLength:=1000,StringTextContent:="TEXT") Selenium_LoopToSendValueByName(ElementName,NumOfLoops:=1,SleepLength:=1000,StringTextContent:=""){ loop, %NumOfLoops% { try driver.findElementsByName(ElementName).item[1].SendKeys(StringTextContent) catch e { if(A_index = NumOfLoops){ Return "Failed" } sleep, %SleepLength% Continue } Return } } Selenium_LoopToSendValueToXpath(Xpath,NumOfLoops:=1,SleepLength:=1000,StringTextContent:=""){ loop, %NumOfLoops% { ; ToolTip, Loop attempt: %A_index% try driver.FindElementByXPath(Xpath).sendKeys(StringTextContent) ; Click on "upload image" button catch e { if(A_index = NumOfLoops){ Return "Failed" } sleep, %SleepLength% Continue } Return } } Selenium_LoopToClickXpath(Xpath,NumOfLoops:=1,SleepLength:=1000){ loop, %NumOfLoops% { try driver.FindElementByXPath(Xpath).click() catch e { if(A_index = NumOfLoops){ Return "Failed" } sleep, %SleepLength% Continue } Return } } Selenium_LoopToClickXpathAndWaitForOpenWindow(Xpath,NumOfLoops:=1,SleepLength:=1000,WindowName:="Open"){ loop, %NumOfLoops% { ; TooltipThis("Clicking xpath") try driver.FindElementByXPath(Xpath).click() catch e { if(A_index = NumOfLoops){ Return "Failed to Click Xpath or Open File window did not show up on click" } sleep, %SleepLength% Continue } ; tooltipthis("Checking if window exists") sleep, 1000 ; Msgbox % "WindowName: " WindowName if(!WinExist(WindowName)){ Message = %WindowName% not found on %A_index% attempt. ; tooltipthis("Window not found") sleep, %SleepLength% Continue } Return } } Selenium_LoopToClearXpath(Xpath,NumOfLoops:=1,SleepLength:=1000){ loop, %NumOfLoops% { try driver.FindElementByXPath(Xpath).clear() catch e { if(A_index = NumOfLoops){ Return "Failed" } sleep, %SleepLength% Continue } Return } } ;---\Selenium--- ;------------------------------------------------ ; -------------------------------Javascript------------------------------- ReturnAndDisplayJSData(jsref){ ; msgbox, here goes ; https://www.w3schools.com/jsref/dom_obj_all.asp ; -----TEXT CONTENT----- js = return %jsref%.textContent; try status := driver.executeScript(js) OnMessage(0x44, "OnMsgBoxJSReturnData") MsgBox 0x3,.TextContent:,%status% OnMessage(0x44, "") /* */ IfMsgBox Yes,{ } Else IfMsgBox No, { TextForClip = js = %js% `n try, status := driver.executeScript(js) Clipboard := TextForClip } Else IfMsgBox Cancel, { return } ; -----VALUE----- js = return %jsref%.value; try status := driver.executeScript(js) OnMessage(0x44, "OnMsgBoxJSReturnData") MsgBox 0x3,.value:,%status% OnMessage(0x44, "") /* */ IfMsgBox Yes,{ } Else IfMsgBox No, { TextForClip = js = %js% `n try, status := driver.executeScript(js) Clipboard := TextForClip } Else IfMsgBox Cancel, { return } ; -----INNERTEXT----- js = return %jsref%.innerText; try status := driver.executeScript(js) OnMessage(0x44, "OnMsgBoxJSReturnData") MsgBox 0x3, .innerText,%status% OnMessage(0x44, "") /* */ IfMsgBox Yes,{ } Else IfMsgBox No, { TextForClip = js = %js% `n try, status := driver.executeScript(js) Clipboard := TextForClip } Else IfMsgBox Cancel, { return } ; -----OuterText----- js = return %jsref%.outerText; try status := driver.executeScript(js) OnMessage(0x44, "OnMsgBoxJSReturnData") MsgBox 0x3, .outerText,%status% OnMessage(0x44, "") /* */ IfMsgBox Yes,{ } Else IfMsgBox No, { TextForClip = js = %js% `n try, status := driver.executeScript(js) Clipboard := TextForClip } Else IfMsgBox Cancel, { return } ;-----innerHTML----- js = return %jsref%.innerHTML; try status := driver.executeScript(js) OnMessage(0x44, "OnMsgBoxJSReturnData") MsgBox 0x3, .innerHTML,%status% OnMessage(0x44, "") /* */ IfMsgBox Yes,{ } Else IfMsgBox No, { TextForClip = js = %js% `n try, status := driver.executeScript(js) Clipboard := TextForClip } Else IfMsgBox Cancel, { return } ; -----outerHTML----- js = return %jsref%.outerHTML; try status := driver.executeScript(js) OnMessage(0x44, "OnMsgBoxJSReturnData") MsgBox 0x3, .outerHTML,%status% OnMessage(0x44, "") /* */ IfMsgBox Yes,{ } Else IfMsgBox No, { TextForClip =js = %js% `n try,status := driver.executeScript(js) Clipboard := TextForClip } Else IfMsgBox Cancel, { return } } /* */ OnMsgBoxJSReturnData() { DetectHiddenWindows, On Process, Exist If (WinExist("ahk_class #32770 ahk_pid " . ErrorLevel)) { ControlSetText Button1, OK ControlSetText Button2, Copy ControlSetText Button3, Return } }