wisem2540 Posted May 3, 2018 Share Posted May 3, 2018 I am not a pro at all with IE automation. I am hoping someone can help me make this better. 1. In the first area of the script, I am assuming that I am going to get a cert mismatch error, still testing the getlink function to click CONTINUE. The question is, how can I have it watch for this error rather than assuming it will appear? 2. In the second part of the script, I am returning the info for the LOGIN button. Rather than using Sleep (1000), how can I have it wait until the LOGIN button is visible? 3. In my functions, rather than looping through and waiting until name= and ID=, is there an easier way to target these directly, since I know what values I am waiting for? Thanks expandcollapse popupGUICtrlSetData($Label0, "Resetting Camera"); Set Label $oIE = _IECreate("http://"&$IP,0,$showIE) Sleep (1000) Call ("getlink") Local $link = _IEGetObjByName ($oie, $buttonid) _IEAction($link, "click") _IELoadWait ($oIE) Sleep (1000) Call ("getbutton","button") Local $userfield = _IEGetObjByName($oie, "username") Local $passwordfield = _IEGetObjByName($oie, "password") Local $loginbutton = _IEGetObjByName ($oie, $buttonid) _IEFormElementSetValue($userfield, $user) _IEFormElementSetValue($passwordfield, $password) _IEAction($loginbutton, "click") Sleep (2000) Call ("getbutton2") Local $shutdownbutton = _IEGetObjByName ($oie, $buttonid) _IEAction($shutdownbutton, "click") _IELoadWait ($oIE) Sleep (1000) Local $userfield = _IEGetObjByName($oie, "shutdownusername") Local $passwordfield = _IEGetObjByName($oie, "Shutdownpassword") _IEFormElementSetValue($userfield, $user) _IEFormElementSetValue($passwordfield, $password) Call ("getbutton3") Local $restartbutton = _IEGetObjByName ($oie, $buttonid) _IEAction($restartbutton, "click") _IEQuit ($oIE) AdlibRegister ("Pingip"); start ping Func getbutton($text) $oInputs = _IETagNameGetCollection($oIE, $text) For $oInput In $oInputs $buttonid = $oInput.id Next EndFunc Func getbutton2() $oInputs = _IETagNameAllGetCollection($oIE) For $oInput In $oInputs $buttonid = $oInput.id $buttonname = $oInput.tagname $innertext = $oInput.innerText If $buttonname = "A" and StringInStr($innertext,"Shutdown") Then Return Next EndFunc Func getbutton3() $oInputs = _IETagNameAllGetCollection($oIE) For $oInput In $oInputs $buttonid = $oInput.id $buttonname = $oInput.tagname $innertext = $oInput.innerText If $buttonname = "button" and StringInStr($innertext,"Restart") Then Return Next EndFunc Func getlink() $oInputs = _IETagNameAllGetCollection($oIE) For $oInput In $oInputs $buttonid = $oInput.id $buttonname = $oInput.tagname $innertext = $oInput.innerText MsgBox (0, $buttonid, $Buttonname) ;If $buttonname = "overridelink" Then Return Next EndFunc Link to comment Share on other sites More sharing options...
Danp2 Posted May 4, 2018 Share Posted May 4, 2018 Some general observations -- Never understood why people insist on using Call() in this fashion. Why not just do this? GetLink() GetButton("button") etc Is there a reason you are using _IETagNameAllGetCollection instead of _IETagNameGetCollection, which would allow you to target specific types of elements? Would help if you posted the associated HTML code so that we can get a better idea of what elements you are trying to access Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
wisem2540 Posted May 4, 2018 Author Share Posted May 4, 2018 If I recall, I chose GETALLCOLLECTION because the IDs are dynamic and change all the time. This was the only way I could get it to work. But as I said, I am a novice as IE automation, which is why I am here. Here is the code for the buttons I need to target. This element I want to monitor for, and only click it if it appears <a name="overridelink" id="overridelink" href="https://10.10.10.10/">Continue to this website (not recommended).</a> This is the first login button and again the ID changes every time the page loads <button class="Wt-btn" id="oi9c5qr" onclick="var e=event||window.event,o=this;if($(o).hasClass('Wt-disabled')){Wt3_2_3.cancelEvent(e);return;}Wt._p_.update(o,'s3bc',e,true);" type="button"> Login </button> This is the "shutdown button" on the next page <a id="oi9c3pe" onclick="var e=event||window.event,o=this;if(e.ctrlKey||e.metaKey||(Wt3_2_3.button(e) > 1))return true;else{if($(o).hasClass('Wt-disabled')){Wt3_2_3.cancelEvent(e);return;}Wt3_2_3.cancelEvent(e,0x2);Wt._p_.update(o,'s4ae',e,true);}" href="/?_=/admin/shutdown"><span id="oi9c3pd" style="white-space: nowrap;"> Shutdown </span></a> and finally this is the restart button that restarts the camera <button class="Wt-btn radio" id="oi9c3sl" onclick="var e=event||window.event,o=this;if($(o).hasClass('Wt-disabled')){Wt3_2_3.cancelEvent(e);return;}Wt._p_.update(o,'s4a3',e,true);" type="button"> Restart </button> Link to comment Share on other sites More sharing options...
wisem2540 Posted May 4, 2018 Author Share Posted May 4, 2018 Here is a script provided by the vendor that shows how they targeted the elements with powershell. expandcollapse popup<#*********************************************************************************************** * * Author: Brandon Moser * * Purpose: Reboot HD40 endpoints programmatically * * Date: 2016.02.29 * * Version: 1.1 * ************************************************************************************************#> # Set variables (accepts input at command-line: -switch [val])********************************** Param( [string]$inputFile = ".\rebootLoopInput.txt", [string]$username = "user", [string]$password = "password", [ipAddress]$url = "0.0.0.0", [int]$timeoutMilliseconds = "10000" ) # FUNCTIONS *********************************************************************************** # Pause function; waits for IE comObject to finish loading current page. Conditional wait followed # by hard wait to allow DOM to render. Hard wait not as elegant as checking for innerHtml load (TODO) function loadWait() { while( $ie.ReadyState -ne 4 -or $ie.Busy ){Start-Sleep -m 100} Start-sleep -s 1 } # end of function loadWait() # Wait for elementMatchText to show up in elementID or timeoutMilleseconds to elapse function domWaitID($elementID, $elementMatchText) { $timeout = 0 $timeStart = Get-Date do { while( $ie.ReadyState -ne 4 -or $ie.Busy ){Start-Sleep -m 100} if ( $ie.ReadyState -eq 4 ) { $elementText = (($ie.Document).getElementByID("$elementID")).innerText $elementMatch = $elementText -match $elementMatchText if ( $elementMatch ) { $loadTime = (Get-Date).Subtract($timeStart) } } $timeout = ((Get-Date).subtract($timeStart)).TotalMilliseconds -gt $timeoutMilliseconds $exitFlag = $elementMatch -or $timeout } until ( $exitFlag ) } # Wait for elementMatchText to show up in inner HTML function domWaitHREF($elementMatchText) { $timeout = 0 $timeStart = Get-Date do { while( $ie.ReadyState -ne 4 -or $ie.Busy ){Start-Sleep -m 100} if ( $ie.ReadyState -eq 4 ) { $elementText = $ie.document.getElementsByTagName('a') | ? { $_.href -match $elementMatchText} | Select $elementMatch = $elementText.innerText -match $elementMatchText if ( $elementMatch ) { $loadTime = (Get-Date).Subtract($timeStart) } } $timeout = ((Get-Date).subtract($timeStart)).TotalMilliseconds -gt $timeoutMilliseconds $exitFlag = $elementMatch -or $timeout } until ( $exitFlag ) } # Main function function doCrawl() { Param( [ipAddress]$url ) write-host "Working IP" $url.ToString() # Go to the IP $ie.Navigate( "$url" ) # Wait for it to load while( $ie.ReadyState -ne 4 -or $ie.Busy ){Start-Sleep -m 1} # Skip cert errors (thank you, Vidyo, for those) if ($ie.document.url -Match "SSLerror") { #"Bypassing SSL Certificate Error Page"; # Shhhh... so noisy $sslbypass=$ie.Document.getElementsByTagName("a") | where-object {$_.name -eq "overridelink"}; $sslbypass.click(); #"Sleep while final page loads"; # Yeah, more noise Start-Sleep -s 1; while( $ie.ReadyState -ne 4){Start-Sleep -m 100}; } # Ensure the login page loads domWaitID "username" "" # Populate user/password fields. Defaults are plaintext in this file, sorry. Defined in variable definitions, above. $ie.document.getElementByID("username").value = $username $ie.document.getElementByID("password").value = $password # Click the login button (Ermergerd; this took way longer than it should have to figure out. # Essentially had everything right yesterday, but hafta add the Select statement to allow # the Click() method to proc without throwing errors) $clicky = $ie.document.getelementsbytagname('button') | Select $clicky.click() # Wait for post-login page to load domWaitHREF "shutdown" # Find and click the Shutdown page link #Start-sleep -s 1 $shutdownLink = $ie.document.getElementsByTagName('a') | ? { $_.href -match "shutdown"} | Select $shutdownLink.Click() # Ensure the Shutdown page loads domWaitHREF "shutdown" # Populate user/password fields in shutdown page. They're plaintext in this file, sorry. Defined in variable definitions, above. write-host $ie.document.outerHTML $ie.document.getElementByID("shutdownusername").value = "$username" $ie.document.getElementByID("shutdownpassword").value = "$password" # Click the Restart button $clickyReboot = $ie.document.getElementsByTagName('button') | ? { $_.innerText -match "Restart"} | Select $clickyReboot.click() write-host $url "is rebooting." loadWait } # End of main method doCrawl() # Core code ***************************************************************************** # Irrelevant; we're not catching errors. $ErrorActionPreference = "continue" # Clear (lol) clear # Launch a new IE object; we only want to do this once per script run and iterate through all IP # addresses before closing it. $ie = New-Object -comobject InternetExplorer.Application # Change next line to $true if you want to see the magic happen onscreen. Might be useful to troubleshoot, as # the non-existant error-trap tends to quash any useful text tossed onscreen $ie.visible = $true $ie.silent = $false # Call main method Get-Content $inputFile | ForEach-Object {doCrawl -url $_ } # Close the browser instance $ie.Quit() Link to comment Share on other sites More sharing options...
Danp2 Posted May 4, 2018 Share Posted May 4, 2018 1 hour ago, wisem2540 said: if ($ie.document.url -Match "SSLerror") You could perform a similar check after using _IEPropertyGet to retrieve the current URL. If found, then retrieve / click the link Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Danp2 Posted May 4, 2018 Share Posted May 4, 2018 For the other stuff, there are lots of examples on the forum of using _IETagNameGetCollection and then looping through the matching elements. Here are a couple of examples -- Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
wisem2540 Posted May 4, 2018 Author Share Posted May 4, 2018 1 hour ago, Danp2 said: You could perform a similar check after using _IEPropertyGet to retrieve the current URL. If found, then retrieve / click the link I will check this out for sure. Thanks. As for the looping through to get the matching elements... Isn't that pretty much what I am already doing? I was hoping, since I already know the strings I am looking for, that I could target them directly. Link to comment Share on other sites More sharing options...
Danp2 Posted May 4, 2018 Share Posted May 4, 2018 Yes, except that you are looping through all elements. If you switch to _IETagNameGetCollection, then you can reduce the elements search to a specific type (button, link, input, etc). As far as directly targeting an element, you could look into querySelector (search the forum for examples) or jQuerify. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now