Powershell Website Automation: Javascript Popup Box Freeze

戏子无情 提交于 2019-12-23 04:28:13

问题


I am trying to automate a process in which the user downloads a file extract from a website. My issue is that once the 'export' button in clicked, a javascript popup window comes up with various date parameters for the extract along with the final 'DOWNLOAD' button that needs to be clicked. The problem arises during this javascript popup window. Once the export button is clicked and the popup window opens, powershell seems to freeze up during the script and will not allow any further commands to be executed.

I have tried using the WASP module along with SELECT-WINDOW in order to grab the correct IE process window, however the 'Select-Window -Title "NAME OF POPUP WINDOW - Windows Internet Explorer" | Select -First 1 | Set-WindowActive' command will not execute as Powershell gets stuck 'Running script' immediately after the initial 'export' button is clicked (right when the popup window opens). Is there a way I can either 'refresh' Powershell after the popup box is opened in order to execute further commands, or any ideas on a way to break out of the continuous 'Running script' loop that I get stuck in with this Javascrip popup window?

# Set access URL and Credentials
$WebU='username'
$WebP='password'
$URLlogin='http://websiteurl.com'
$IEwait="1000"
# Execute IE and navigate to URL
$ie = New-Object -com "InternetExplorer.application";
$ie.visible = $True;
$ie.navigate($URLlogin);

Try{
# Login steps
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("txtLogin"))
    { $ie.Document.getElementByID("txtLogin").value = $WebU }
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("txtPassword"))
    { $ie.Document.getElementByID("txtPassword").value = $WebP }
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("btnLogin"))
    { $ie.Document.getElementByID("btnLogin").Click() }
# Navigate through website to find the 'Export' button
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
if ($ie.Document.getElementByID("managementMenu_btnLearningResults"))
    { $ie.Document.getElementByID("managementMenu_btnLearningResults").Click() } 
while ($ie.Busy ) { Start-Sleep -Milliseconds $IEwait; }
# This is the part that freezes the script. Once the 'btnExport' button is clicked, a JS popup keeps Powershell from executing any additional commands
if ($ie.Document.getElementByID("btnExport"))
    { $ie.Document.getElementByID("btnExport").Click() } 
# Once the popoup box opens, sending the 'ENTER' key should automatically download the export file
Select-Window -Title "NAME OF POPUP WINDOW - Windows Internet Explorer" | Select -First 1 | Set-WindowActive
Select-Window -Title "NAME OF POPUP WINDOW - Windows Internet Explorer" | Select-childwindow | Send-Keys "{ENTER}"
}
# These won't execute because the JS popup window confuses Powershell and keeps it in a continuous 'Running Script' process
Catch {
    "Error" }
Finally {
    "Now able to execute further commands" }

回答1:


This problem comes up a lot when automating GUI browsers - modal dialogs like the JS popup you describe will block your script from finishing until someone dismisses it. This is because the call you made into browser itself (which caused the modal dialog to appear) is also blocking, waiting for interaction from the user.

In my experience the easiest way to deal with this scenario is to launch a separate process just to handle the modal dialog. It takes two steps:

  1. Write a small standalone script/program that will wait for the modal dialog to appear, then dismiss it. This is easy to test by launching the popup-handling script manually, then manually performing the steps that make the dialog appear.

  2. Once you have that working, in your main program that automates the browser, launch your separate dialog-handling script just before you execute the line of code that creates the modal dialog.

And that's it. It feels clunky but it will work in pretty much any case I've seen (unless the modal dialog requires elevated security privileges, which brings up other issues).

Also, if you're using a programming language that has native thread support, you can launch a separate thread (instead of a process) to handle modal dialogs.

Some test automators feel it's actually cheaper (in terms of script development and maintenance time) to simply bypass modal dialogs like this if possible, assuming you can get around it and still feel confident in your testing. Sometimes this might require modifying the application to give your test code a special interface into the system.




回答2:


The IE object model is actually kind of treacherous. It often says things are ready when they aren't, because an underlying resource hasn't yet loaded. I got annoyed rewriting this code each time I had to interact with a page, so I wrote a module called AutoBrowse to deal with it:

http://autobrowse.start-automating.com/

Use this instead, and you will sidestep the issue.

Hope this helps




回答3:


    While ( $ie.busy -eq $true){ 
        [System.Threading.Thread]::Sleep(2000); 
        $wshell = New-Object -ComObject wscript.shell;
        if($wshell.AppActivate('Message from webpage'))
        {
            [System.Threading.Thread]::Sleep(1000); 
            [System.Windows.Forms.SendKeys]::SendWait('{Enter}')
        }
    }


来源:https://stackoverflow.com/questions/17303636/powershell-website-automation-javascript-popup-box-freeze

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!